summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/inlining
Commit message (Collapse)AuthorAgeFilesLines
...
* [analyzer] Print a diagnostic note even if the region cannot be printed.Anna Zaks2013-04-121-0/+213
| | | | | | | | | There are few cases where we can track the region, but cannot print the note, which makes the testing limited. (Though, I’ve tested this manually by making all regions non-printable.) Even though the applicability is limited now, the enhancement will be more relevant as we start tracking more regions. llvm-svn: 179396
* [analyzer]Print field region even when the base region is not printableAnna Zaks2013-04-121-0/+263
| | | | llvm-svn: 179395
* [analyzer] Show "Returning from ..." note at caller's depth, not callee's.Jordan Rose2013-04-124-12/+12
| | | | | | | | | | | | | | | | | | | | | | | | Before: 1. Calling 'foo' 2. Doing something interesting 3. Returning from 'foo' 4. Some kind of error here After: 1. Calling 'foo' 2. Doing something interesting 3. Returning from 'foo' 4. Some kind of error here The location of the note is already in the caller, not the callee, so this just brings the "depth" attribute in line with that. This only affects plist diagnostic consumers (i.e. Xcode). It's necessary for Xcode to associate the control flow arrows with the right stack frame. <rdar://problem/13634363> llvm-svn: 179351
* [analyzer] Don't emit extra context arrow after returning from an inlined call.Jordan Rose2013-04-125-408/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In this code int getZero() { return 0; } void test() { int problem = 1 / getZero(); // expected-warning {{Division by zero}} } we generate these arrows: +-----------------+ | v int problem = 1 / getZero(); ^ | +---+ where the top one represents the control flow up to the first call, and the bottom one represents the flow to the division.* It turns out, however, that we were generating the top arrow twice, as if attempting to "set up context" after we had already returned from the call. This resulted in poor highlighting in Xcode. * Arguably the best location for the division is the '/', but that's a different problem. <rdar://problem/13326040> llvm-svn: 179350
* [analyzer] Fix null tracking for the given test case, by using the proper ↵Anna Zaks2013-04-051-0/+18
| | | | | | state and removing redundant code. llvm-svn: 178933
* [analyzer] Show path diagnostic for C++ initializersAnna Zaks2013-04-051-12/+388
| | | | | | Also had to modify the PostInitializer ProgramLocation to contain the field region. llvm-svn: 178826
* [analyzer] Allow tracknullOrUndef look through the ternary operator even ↵Anna Zaks2013-04-031-3/+4
| | | | | | | | | | | | | when condition is unknown Improvement of r178684 and r178685. Jordan has pointed out that I should not rely on the value of the condition to know which expression branch has been taken. It will not work in cases the branch condition is an unknown value (ex: we do not track the constraints for floats). The better way of doing this would be to find out if the current node is the right or left successor of the node that has the ternary operator as a terminator (which is how this is done in other places, like ConditionBRVisitor). llvm-svn: 178701
* [analyzer] make peelOffOuterExpr in BugReporterVisitors recursively peel off ↵Anna Zaks2013-04-031-0/+25
| | | | | | select Exprs llvm-svn: 178685
* [analyzer] Properly handle the ternary operator in trackNullOrUndefValueAnna Zaks2013-04-031-1/+4
| | | | | | | | | | | | 1) Look for the node where the condition expression is live when checking if it is constrained to true or false. 2) Fix a bug in ProgramState::isNull, which was masking the problem. When the expression is not a symbol (,which is the case when it is Unknown) return unconstrained value, instead of value constrained to “false”! (Thankfully other callers of isNull have not been effected by the bug.) llvm-svn: 178684
* [analyzer] For now, don't inline [cd]tors of C++ containers.Jordan Rose2013-04-022-2/+236
| | | | | | | | | | | | | | | | | | | | | This is a heuristic to make up for the fact that the analyzer doesn't model C++ containers very well. One example is modeling that 'std::distance(I, E) == 0' implies 'I == E'. In the future, it would be nice to model this explicitly, but for now it just results in a lot of false positives. The actual heuristic checks if the base type has a member named 'begin' or 'iterator'. If so, we treat the constructors and destructors of that type as opaque, rather than inlining them. This is intended to drastically reduce the number of false positives reported with experimental destructor support turned on. We can tweak the heuristic in the future, but we'd rather err on the side of false negatives for now. <rdar://problem/13497258> llvm-svn: 178516
* [analyzer] Address Jordan’s review of r178309 - do not register an extra ↵Anna Zaks2013-03-291-0/+16
| | | | | | | | | | | | visitor for nil receiver We can check if the receiver is nil in the node that corresponds to the StmtPoint of the message send. At that point, the receiver is guaranteed to be live. We will find at least one unreclaimed node due to my previous commit (look for StmtPoint instead of PostStmt) and the fact that the nil receiver nodes are tagged. + a couple of extra tests. llvm-svn: 178381
* [analyzer] Apply the suppression rules to the nil receiver only if the value ↵Anna Zaks2013-03-281-1/+68
| | | | | | | | | | | | | | participates in the computation of the nil we warn about. We should only suppress a bug report if the IDCed or null returned nil value is directly related to the value we are warning about. This was not the case for nil receivers - we would suppress a bug report that had an IDCed nil receiver on the path regardless of how it’s related to the warning. 1) Thread EnableNullFPSuppression parameter through the visitors to differentiate between tracking the value which is directly responsible for the bug and other values that visitors are tracking (ex: general tracking of nil receivers). 2) in trackNullOrUndef specifically address the case when a value of the message send is nil due to the receiver being nil. llvm-svn: 178309
* [analyzer] Fix test to actually test what was intended.Jordan Rose2013-03-221-2/+2
| | | | llvm-svn: 177763
* [analyzer] BugReporterVisitors: handle the case where a ternary operator is ↵Anna Zaks2013-03-151-0/+11
| | | | | | wrapped in a cast. llvm-svn: 177205
* [analyzer] Look through ExprWhenCleanups when trying to track a NULL.Jordan Rose2013-03-151-5/+41
| | | | | | Silences a few false positives in LLVM. llvm-svn: 177186
* [analyzer] Teach trackNullOrUndef to look through ternary operatorsAnna Zaks2013-03-151-0/+36
| | | | | | Allows the suppression visitors trigger more often. llvm-svn: 177137
* [analyzer] Change the way in which IDC Visitor decides to kick in and make ↵Anna Zaks2013-03-141-1/+24
| | | | | | | | | | | | | sure it attaches in the given edge case In the test case below, the value V is not constrained to 0 in ErrorNode but it is in node N. So we used to fail to register the Suppression visitor. We also need to change the way we determine that the Visitor should kick in because the node N belongs to the ExplodedGraph and might not be on the BugReporter path that the visitor sees. Instead of trying to match the node, turn on the visitor when we see the last node in which the symbol is ‘0’. llvm-svn: 177121
* [analyzer] BugReporter - more precise tracking of C++ referencesAnna Zaks2013-03-131-0/+49
| | | | | | | | | | | | | | | | When BugReporter tracks C++ references involved in a null pointer violation, we want to differentiate between a null reference and a reference to a null pointer. In the first case, we want to track the region for the reference location; in the second, we want to track the null pointer. In addition, the core creates CXXTempObjectRegion to represent the location of the C++ reference, so teach FindLastStoreBRVisitor about it. This helps null pointer suppression to kick in. (Patch by Anna and Jordan.) llvm-svn: 176969
* [analyzer] Make Suppress IDC checker aware that it might not start from the ↵Anna Zaks2013-03-091-0/+32
| | | | | | | | | | | | | | | | | | | | same node it was registered at The visitor used to assume that the value it’s tracking is null in the first node it examines. This is not true. If we are registering the Suppress Inlined Defensive checks visitor while traversing in another visitor (such as FindlastStoreVisitor). When we restart with the IDC visitor, the invariance of the visitor does not hold since the symbol we are tracking no longer exists at that point. I had to pass the ErrorNode when creating the IDC visitor, because, in some cases, node N is neither the error node nor will be visible along the path (we had not finalized the path at that point and are dealing with ExplodedGraph.) We should revisit the other visitors which might not be aware that they might get nodes, which are later in path than the trigger point. This suppresses a number of inline defensive checks in JavaScriptCore. llvm-svn: 176756
* [analyzer] Look for lvalue nodes when tracking a null pointer.Jordan Rose2013-03-081-0/+419
| | | | | | | | | | | | | | | | | | r176010 introduced the notion of "interesting" lvalue expressions, whose nodes are guaranteed never to be reclaimed by the ExplodedGraph. This was used in bugreporter::trackNullOrUndefValue to find the region that contains the null or undef value being tracked. However, the /rvalue/ nodes (i.e. the loads from these lvalues that produce a null or undef value) /are/ still being reclaimed, and if we couldn't find the node for the rvalue, we just give up. This patch changes that so that we look for the node for either the rvalue or the lvalue -- preferring the former, since it lets us fall back to value-only tracking in cases where we can't get a region, but allowing the latter as well. <rdar://problem/13342842> llvm-svn: 176737
* [analyzer] Check for returning null references in ReturnUndefChecker.Jordan Rose2013-03-072-0/+130
| | | | | | | | | | | | | | | | | Officially in the C++ standard, a null reference cannot exist. However, it's still very easy to create one: int &getNullRef() { int *p = 0; return *p; } We already check that binds to reference regions don't create null references. This patch checks that we don't create null references by returning, either. <rdar://problem/13364378> llvm-svn: 176601
* [analyzer] Pass the correct Expr to the bug reporter visitors when dealing ↵Anna Zaks2013-03-061-0/+46
| | | | | | | | with CompoundLiteralExpr This allows us to trigger the IDC visitor in the added test case. llvm-svn: 176577
* [analyzer] IDC: Add config option; perform the idc check on first “null ↵Anna Zaks2013-03-061-1/+1
| | | | | | | | | | node” rather than last “non-null”. The second modification does not lead to any visible result, but, theoretically, is what we should have been looking at to begin with since we are checking if the node was assumed to be null in an inlined function. llvm-svn: 176576
* [analyzer] Simple inline defensive checks suppressionAnna Zaks2013-03-022-714/+389
| | | | | | | | | | | | | | | | | | | | | Inlining brought a few "null pointer use" false positives, which occur because the callee defensively checks if a pointer is NULL, whereas the caller knows that the pointer cannot be NULL in the context of the given call. This is a first attempt to silence these warnings by tracking the symbolic value along the execution path in the BugReporter. The new visitor finds the node in which the symbol was first constrained to NULL. If the node belongs to a function on the active stack, the warning is reported, otherwise, it is suppressed. There are several areas for follow up work, for example: - How do we differentiate the cases where the first check is followed by another one, which does happen on the active stack? Also, this only silences a fraction of null pointer use warnings. For example, it does not do anything for the cases where NULL was assigned inside a callee. llvm-svn: 176402
* [analyzer] Suppress paths involving a reference whose rvalue is null.Jordan Rose2013-03-012-5/+776
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Most map types have an operator[] that inserts a new element if the key isn't found, then returns a reference to the value slot so that you can assign into it. However, if the value type is a pointer, it will be initialized to null. This is usually no problem. However, if the user /knows/ the map contains a value for a particular key, they may just use it immediately: // From ClangSACheckersEmitter.cpp recordGroupMap[group]->Checkers In this case the analyzer reports a null dereference on the path where the key is not in the map, even though the user knows that path is impossible here. They could silence the warning by adding an assertion, but that means splitting up the expression and introducing a local variable. (Note that the analyzer has no way of knowing that recordGroupMap[group] will return the same reference if called twice in a row!) We already have logic that says a null dereference has a high chance of being a false positive if the null came from an inlined function. This patch simply extends that to references whose rvalues are null as well, silencing several false positives in LLVM. <rdar://problem/13239854> llvm-svn: 176371
* [analyzer] Teach FindLastStoreBRVisitor to understand stores of the same value.Jordan Rose2013-02-271-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | Consider this case: int *p = 0; p = getPointerThatMayBeNull(); *p = 1; If we inline 'getPointerThatMayBeNull', we might know that the value of 'p' is NULL, and thus emit a null pointer dereference report. However, we usually want to suppress such warnings as error paths, and we do so by using FindLastStoreBRVisitor to see where the NULL came from. In this case, though, because 'p' was NULL both before and after the assignment, the visitor would decide that the "last store" was the initialization, not the re-assignment. This commit changes FindLastStoreBRVisitor to consider all PostStore nodes that assign to this region. This still won't catches changes made directly by checkers if they re-assign the same value, but it does handle the common case in user-written code and will trigger ReturnVisitor's suppression machinery as expected. <rdar://problem/13299738> llvm-svn: 176201
* [analyzer] Use 'MemRegion::printPretty()' instead of assuming the region is ↵Ted Kremenek2013-02-263-27/+27
| | | | | | | | | | | | a VarRegion. Fixes PR15358 and <rdar://problem/13295437>. Along the way, shorten path diagnostics that say "Variable 'x'" to just be "'x'". By the context, it is obvious that we have a variable, and so this just consumes text space. llvm-svn: 176115
* [analyzer] Restrict ObjC type inference to methods that have related result ↵Anna Zaks2013-02-251-0/+17
| | | | | | | | | | | | type. This addresses a case when we inline a wrong method due to incorrect dynamic type inference. Specifically, when user code contains a method from init family, which creates an instance of another class. Use hasRelatedResultType() to find out if our inference rules should be triggered. llvm-svn: 176054
* [analyzer] Track null object lvalues back through C++ method calls.Jordan Rose2013-01-261-0/+36
| | | | | | | | | | The expression 'a->b.c()' contains a call to the 'c' method of 'a->b'. We emit an error if 'a' is NULL, but previously didn't actually track the null value back through the 'a->b' expression, which caused us to miss important false-positive-suppression cases, including <rdar://problem/12676053>. llvm-svn: 173547
* [analyzer] Replace "-analyzer-ipa" with "-analyzer-config ipa".Anna Zaks2013-01-2410-11/+11
| | | | | | | | | The idea is to eventually place all analyzer options under "analyzer-config". In addition, this lays the ground for introduction of a high-level analyzer mode option, which will influence the default setting for IPAMode. llvm-svn: 173385
* [analyzer] Fix test for r173067.Jordan Rose2013-01-211-110/+110
| | | | | | | Note to self: don't remove comments /after/ updating the line-sensitive part of a test. llvm-svn: 173070
* [analyzer] Show notes inside implicit calls at the last explicit call site.Jordan Rose2013-01-211-126/+126
| | | | | | | | | | | | | | | | | | | Before: struct Wrapper { <-- 2. Calling default constructor for 'NonTrivial'. NonTrivial m; }; Wrapper w; <-- 1. Calling implicit default constructor for 'Wrapper'. After: struct Wrapper { NonTrivial m; }; Wrapper w; <-- 1. Calling implicit default constructor for 'Wrapper'. ^-- 2. Calling default constructor for 'NonTrivial'. llvm-svn: 173067
* [analyzer] Don't show "Entered 'foo'" if 'foo' is implicit.Jordan Rose2013-01-191-84/+0
| | | | | | | | | | | | | | | | Before: Calling implicit default constructor for 'Foo' (where Foo is constructed) Entered call from 'test' (at "=default" or 'Foo' declaration) Calling default constructor for 'Bar' (at "=default" or 'Foo' declaration) After: Calling implicit default constructor for 'Foo' (where Foo is constructed) Calling default constructor for 'Bar' (at "=default" or 'Foo' declaration) This only affects the plist diagnostics; this note is never shown in the other diagnostics. llvm-svn: 172915
* [analyzer] Special path notes for C++ special member functions.Jordan Rose2013-01-181-2/+1751
| | | | | | | | | | | | Examples: Calling implicit default constructor for Foo Calling defaulted move constructor for Foo Calling copy constructor for Foo Calling implicit destructor for Foo Calling defaulted move assignment operator for Foo Calling copy assignment operator for Foo llvm-svn: 172833
* [analyzer] Do a better job describing C++ member functions in the call stack.Jordan Rose2013-01-181-0/+860
| | | | | | | | Examples: Calling constructor for 'Foo' Entered call from 'Foo::create' llvm-svn: 172832
* [analyzer] Plist: change the type of issue_hash from int to string.Anna Zaks2013-01-083-13/+13
| | | | | | This gives more flexibility to what could be stored as issue_hash. llvm-svn: 171824
* [analyzer] Fix r168019 to work with unpruned paths as well.Jordan Rose2012-12-071-0/+265
| | | | | | | | | | | | | This is the case where the analyzer tries to print out source locations for code within a synthesized function body, which of course does not have a valid source location. The previous fix attempted to do this during diagnostic path pruning, but some diagnostics have pruning disabled, and so any diagnostic with a path that goes through a synthesized body will either hit an assertion or emit invalid output. <rdar://problem/12657843> (again) llvm-svn: 169631
* [analyzer] Make sure calls in synthesized functions have valid path locations.Jordan Rose2012-11-151-50/+399
| | | | | | | | | | | | | | | | | | We do this by using the "most recent" good location: if a synthesized function 'A' calls another function 'B', the path notes for the call to 'B' will be placed at the same location as the path note for calling 'A'. Similarly, the call to 'A' will have a note saying "Entered call from...", and now we just don't emit that (since the user doesn't have a body to look at anyway). Previously, we were doing this for the "Calling..." notes, but not for the "Entered call from..." or "Returning to caller". This caused a crash when the path entered and then exiting a call within a synthesized body. <rdar://problem/12657843> llvm-svn: 168019
* [analyzer] Follow up to r167762 - precisely determine the adjustmentAnna Zaks2012-11-121-1/+38
| | | | | | | | | | | | | | | | | conditions. The adjustment is needed only in case of dynamic dispatch performed by the analyzer - when the runtime declaration is different from the static one. Document this explicitly in the code (by adding a helper). Also, use canonical Decls to avoid matching against the case where the definition is different from found declaration. This fix suppresses the testcase I added in r167762, so add another testcase to make sure we do test commit r167762. llvm-svn: 167780
* [analyzer] New option to not suppress null return paths if an argument is null.Jordan Rose2012-10-291-5/+94
| | | | | | | | | | | | | | | | | | 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
* [analyzer] Use the CallEnter node to get a value for tracked null arguments.Jordan Rose2012-10-291-0/+788
| | | | | | | | | | | | | | | | 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
* TrackConstraintBRVisitor and ConditionBRVisitor can emit similarTed Kremenek2012-10-251-299/+269
| | | | | | | | | | | | 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
* Prior to adding the new "expected-no-diagnostics" directive to ↵Andy Gibbs2012-10-191-0/+1
| | | | | | VerifyDiagnosticConsumer, make the necessary adjustment to 580 test-cases which will henceforth require this new directive. llvm-svn: 166280
* Revert "InlineObjCInstanceMethod.m: Remove lines introduced in r165079."Jordan Rose2012-10-031-1/+26
| | | | | | | | | ...and fix the run line so that the expected warnings are the same on all platforms. This reverts r165088 / d09074f0ca06626914108f1c0d4e70adeb851e01. llvm-svn: 165124
* InlineObjCInstanceMethod.m: Remove lines introduced in r165079. It broke ↵NAKAMURA Takumi2012-10-031-25/+0
| | | | | | | | | | some builds, on FreeBSD, Linux and Windows. error: 'warning' diagnostics expected but not seen: Line 94: types are incompatible 1 error generated. llvm-svn: 165088
* [analyzer] Adjust the return type of an inlined devirtualized method call.Jordan Rose2012-10-031-1/+26
| | | | | | | | | | | | | | | | | | | | | | | | | 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
* [analyzer] Commit a test case for r164579.Anna Zaks2012-09-261-1/+11
| | | | llvm-svn: 164715
* [analyzer] Really turn on dynamic-bifurcation on by default.Anna Zaks2012-09-241-1/+1
| | | | | | | Thanks to Byoungyoung for realizing taht we are not passing the default option correctly. llvm-svn: 164543
* [analyzer] Suppress bugs whose paths go through the return of a null pointer.Jordan Rose2012-09-223-4/+99
| | | | | | | | | | | | | | | | | | | | 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
* [analyzer] Track a null value back through FindLastStoreBRVisitor.Jordan Rose2012-09-221-50/+481
| | | | | | | Also, tidy up the other tracking visitors so that they mark the right things as interesting and don't do extra work. llvm-svn: 164448
OpenPOWER on IntegriCloud