Commit Graph

34 Commits

Author SHA1 Message Date
Richard Trieu f7432755d0 Add -Wtautological-undefined-compare and -Wundefined-bool-conversion warnings
to detect underfined behavior involving pointers.

llvm-svn: 210372
2014-06-06 21:39:26 +00:00
Anna Zaks 5416ab0156 [analyzer] Use the expression’s type instead of region’s type in ArrayToPointer decay evaluation
This gives slightly better precision, specifically, in cases where a non-typed region represents the array
or when the type is a non-array type, which can happen when an array is a result of a reinterpret_cast.

llvm-svn: 182810
2013-05-28 23:24:01 +00:00
Anna Zaks 05139fff42 [analyzer] Tweak getDerefExpr more to track DeclRefExprs to references.
In the committed example, we now see a note that tells us when the pointer
was assumed to be null.

This is the only case in which getDerefExpr returned null (failed to get
the dereferenced expr) throughout our regression tests. (There were multiple
occurrences of this one.)

llvm-svn: 179736
2013-04-18 00:15:15 +00:00
Jordan Rose b1312a5495 Force a load when creating a reference to a temporary copied from a bitfield.
For this source:
  const int &ref = someStruct.bitfield;

We used to generate this AST:

  DeclStmt [...]
  `-VarDecl [...] ref 'const int &'
    `-MaterializeTemporaryExpr [...] 'const int' lvalue
      `-ImplicitCastExpr [...] 'const int' lvalue <NoOp>
        `-MemberExpr [...] 'int' lvalue bitfield .bitfield [...]
          `-DeclRefExpr [...] 'struct X' lvalue ParmVar [...] 'someStruct' 'struct X'

Notice the lvalue inside the MaterializeTemporaryExpr, which is very
confusing (and caused an assertion to fire in the analyzer - PR15694).

We now generate this:

  DeclStmt [...]
  `-VarDecl [...] ref 'const int &'
    `-MaterializeTemporaryExpr [...] 'const int' lvalue
      `-ImplicitCastExpr [...] 'int' <LValueToRValue>
        `-MemberExpr [...] 'int' lvalue bitfield .bitfield [...]
          `-DeclRefExpr [...] 'struct X' lvalue ParmVar [...] 'someStruct' 'struct X'

Which makes a lot more sense. This allows us to remove code in both
CodeGen and AST that hacked around this special case.

The commit also makes Clang accept this (legal) C++11 code:

  int &&ref = std::move(someStruct).bitfield

PR15694 / <rdar://problem/13600396>

llvm-svn: 179250
2013-04-11 00:58:58 +00:00
Anna Zaks 9e0da9e070 [analyzer] Warn on passing a reference to null pointer as an argument in a call
Warn about null pointer dereference earlier when a reference to a null pointer is
passed in a call. The idea is that even though the standard might allow this, reporting
the issue earlier is better for diagnostics (the error is reported closer to the place where
the pointer was set to NULL). This also simplifies analyzer’s diagnostic logic, which has
to track “where the null came from”. As a consequence, some of our null pointer
warning suppression mechanisms started triggering more often.

TODO: Change the name of the file and class to reflect the new check.
llvm-svn: 176612
2013-03-07 03:02:36 +00:00
Jordan Rose b41977f852 [analyzer] Check for returning null references in ReturnUndefChecker.
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
2013-03-07 01:23:25 +00:00
Jordan Rose 29fc261cd7 [analyzer] Create a temporary region when accessing a struct rvalue.
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
2012-10-17 19:35:37 +00:00
Jordan Rose d60b9168fa Revert "[analyzer] Create a temporary region for rvalue structs when accessing fields"
This reverts commit 6f61df3e7256413dcb99afb9673f4206e3c4992c.

llvm-svn: 164877
2012-09-29 01:36:51 +00:00
Jordan Rose e7126582a4 [analyzer] Create a temporary region for rvalue structs when accessing fields
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
2012-09-28 17:15:12 +00:00
Jordan Rose fcdda36149 [analyzer] Be more forgiving about calling methods on struct rvalues.
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
2012-09-05 17:11:26 +00:00
Jordan Rose bc009d4493 Revert "[analyzer] Treat all struct values as regions (even rvalues)."
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
2012-09-05 17:11:15 +00:00
Jordan Rose 82ae9898ef [analyzer] Treat all struct values as regions (even rvalues).
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
2012-09-01 17:39:09 +00:00
Jordan Rose 2da564380a [analyzer] Always derive a CallEvent's return type from its origin expr.
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
2012-09-01 17:39:00 +00:00
Ted Kremenek 722398f1d4 Fix analyzer tests.
llvm-svn: 162588
2012-08-24 20:39:55 +00:00
Ted Kremenek 326702f1a1 Despite me asking Jordan to do r162313, revert it. We can provide
another way to whitelist these special cases.  This is an intermediate patch.

llvm-svn: 162386
2012-08-22 19:58:20 +00:00
Ted Kremenek a056d62961 Remove BasicConstraintManager. It hasn't been in active service for a while.
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
2012-08-22 19:47:13 +00:00
Jordan Rose 81125c4497 [analyzer] Push "references are non-null" knowledge up to the common parent.
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
2012-08-21 20:52:19 +00:00
Jordan Rose 075d5d2e99 [analyzer] Assume that reference symbols are non-null.
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
2012-08-21 00:27:33 +00:00
Jordan Rose 4aa80e156d [analyzer] Don't assume values bound to references are automatically non-null.
While there is no such thing as a "null reference" in the C++ standard,
many implementations of references (including Clang's) do not actually
check that the location bound to them is non-null. Thus unlike a regular
null dereference, this will not cause a problem at runtime until the
reference is actually used. In order to catch these cases, we need to not
prune out paths on which the input pointer is null.

llvm-svn: 161288
2012-08-04 00:25:30 +00:00
Jordan Rose 9a2eec3826 [analyzer] Add a simple check for initializing reference variables with null.
There's still more work to be done here; this doesn't catch reference
parameters or return values. But it's a step in the right direction.

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

llvm-svn: 161214
2012-08-02 21:33:42 +00:00
Jordan Rose e8a21b73ac [analyzer] Getting an lvalue for a reference field still requires a load.
This was causing a crash in our array-to-pointer logic, since the region
was clearly not an array.

PR13440 / <rdar://problem/11977113>

llvm-svn: 161051
2012-07-31 16:34:07 +00:00
Jordy Rose 09e7c88940 [analyzer] Fix RUN lines for old XFAIL tests, one of which actually works.
llvm-svn: 156921
2012-05-16 16:01:14 +00:00
Eli Friedman 946b7b5bc8 Switch PerformImplicitConversion over to use DefaultLvalueConversion for lvalue-to-rvalue conversion.
llvm-svn: 148874
2012-01-24 22:51:26 +00:00
Ted Kremenek 3f955e6d89 [analyzer] rename all experimental checker packages to have 'experimental' be the common root package.
llvm-svn: 136835
2011-08-03 23:14:55 +00:00
Ted Kremenek a644668193 [analyzer] fix handling of MaterializeTemporaryExpr by binding the result value to
the proper expression.

llvm-svn: 136412
2011-07-28 23:07:36 +00:00
Argyrios Kyrtzidis 9eb02dfa89 [analyzer] Remove '-analyzer-check-objc-mem' flag, the nominee for best misnomer award.
llvm-svn: 126676
2011-02-28 19:49:42 +00:00
Argyrios Kyrtzidis b388f77ad9 [analyzer] Remove '-analyzer-experimental-internal-checks' flag, it doesn't have any checkers associated with it anymore.
llvm-svn: 126440
2011-02-24 21:43:08 +00:00
Zhongxing Xu 7e2a9fd620 If the initializer is an rvalue and the variable is a const reference,
create a temporary object for it.

llvm-svn: 122161
2010-12-19 02:26:37 +00:00
Ted Kremenek 8219b82125 Start migration of static analyzer to using the
implicit lvalue-to-rvalue casts that John McCall
recently introduced.  This causes a whole bunch
of logic in the analyzer for handling lvalues
to vanish.  It does, however, raise a few issues
in the analyzer w.r.t to modeling various constructs
(e.g., field accesses to compound literals).

The .c/.m analysis test cases that fail are
due to a missing lvalue-to-rvalue cast that
will get introduced into the AST.  The .cpp
failures were more than I could investigate in
one go, and the patch was already getting huge.
I have XFAILED some of these tests, and they
should obviously be further investigated.

Some highlights of this patch include:

- CFG no longer requires an lvalue bit for
  CFGElements
- StackFrameContext doesn't need an 'asLValue'
  flag
- The "VisitLValue" path from GRExprEngine has
  been eliminated.

Besides the test case failures (XFAILed), there
are surely other bugs that are fallout from
this change.

llvm-svn: 121960
2010-12-16 07:46:53 +00:00
Jordy Rose 2e22268904 Assignments to reference variables shouldn't kill the variable.
llvm-svn: 105452
2010-06-04 01:14:56 +00:00
Zhongxing Xu 41cdf585c2 CFG: add all LHS of assingments as lvalue. This improves support for C++ reference. Patch by Jordy.
llvm-svn: 105383
2010-06-03 06:23:18 +00:00
Ted Kremenek 2f2692f8ca Rename -cc1 option '-checker-cfref' to '-analyzer-check-objc-mem'.
llvm-svn: 95348
2010-02-05 02:06:54 +00:00
Zhongxing Xu 9635f6f5ef Enhance test case.
llvm-svn: 93101
2010-01-10 02:52:56 +00:00
Zhongxing Xu f1eeb78ffc When binding an rvalue to a reference, create a temporary object. Use
CXXObjectRegion to represent it. 

In Environment, lookup a literal expression before make up a value for it.

llvm-svn: 93047
2010-01-09 09:16:47 +00:00