Previously our edges were completely broken here; now, the final result
is a very simple set of edges in most cases: one up to the "for" keyword
for context, and one into the body of the loop. This matches the behavior
for ObjC for-in loops.
In the AST, however, CXXForRangeStmts are handled very differently from
ObjCForCollectionStmts. Since they are specified in terms of equivalent
statements in the C++ standard, we actually have implicit AST nodes for
all of the semantic statements. This makes evaluation very easy, but
diagnostic locations a bit trickier. Fortunately, the problem can be
generally defined away by marking all of the implicit statements as
part of the top-level for-range statement.
One of the implicit statements in a for-range statement is the declaration
of implicit iterators __begin and __end. The CFG synthesizes two
separate DeclStmts to match each of these decls, but until now these
synthetic DeclStmts weren't in the function's ParentMap. Now, the CFG
keeps track of its synthetic statements, and the AnalysisDeclContext will
make sure to add them to the ParentMap.
<rdar://problem/14038483>
llvm-svn: 183449
Consider the case where a SwitchStmt satisfied isAllEnumCasesCovered()
as well as having no cases at all (i.e. the enum it covers has no
enumerators).
In this case, we should add a successor to repair the CFG.
This fixes PR16212.
llvm-svn: 183237
Neither the compiler nor the analyzer are doing anything with non-VarDecl
decls in the CFG, and having them there creates extra nodes in the
analyzer's path diagnostics. Simplify the CFG (and the path edges) by
simply leaving them out. We can always add interesting decls back in when
they become relevant.
Note that this only affects decls declared in a DeclStmt, and then only
those that appear within a function body.
llvm-svn: 183157
Ted and I spent a long time discussing this today and found out that neither
the existing code nor the new code was doing what either of us thought it
was, which is never good. The good news is we found a much simpler way to
fix the motivating test case (an ObjCSubscriptExpr).
This reverts r182083, but pieces of it will come back in subsequent commits.
llvm-svn: 182185
assert_exclusive_lock and assert_shared_lock. These attributes are used to
mark functions that dynamically check (i.e. assert) that a lock is held.
llvm-svn: 182170
This optimizes some spurious edges resulting from PseudoObjectExprs.
This required far more changes than I anticipated. The current
ParentMap does not record any hierarchy information between
a PseudoObjectExpr and its *semantic* expressions that may be
wrapped in OpaqueValueExprs, which are the expressions actually
laid out in the CFG. This means the arrow pruning logic could
not map from an expression to its containing PseudoObjectExprs.
To solve this, this patch adds a variant of ParentMap that
returns the "semantic" parentage of expressions (essentially
as they are viewed by the CFG). This alternate ParentMap is then
used by the arrow reducing logic to identify edges into pseudo
object expressions, and then eliminate them.
llvm-svn: 182083
This class is a StmtVisitor that distinguishes between block-level and
non-block-level statements in a CFG. However, it does so using a hard-coded
idea of which statements might be block-level, which probably isn't accurate
anymore. The only implementer of the CFGStmtVisitor hierarchy was the
analyzer's DeadStoresChecker, and the analyzer creates a linearized CFG
anyway (every non-trivial statement is a block-level statement).
This also allows us to remove the block-expr map ("BlkExprMap"), which
mapped statements to positions in the CFG. Apart from having a helper type
that really should have just been Optional<unsigned>, it was only being
used to ask /if/ a particular expression was block-level, for traversal
purposes in CFGStmtVisitor.
llvm-svn: 181945
The most common (non-buggy) case are where such objects are used as
return expressions in bool-returning functions or as boolean function
arguments. In those cases I've used (& added if necessary) a named
function to provide the equivalent (or sometimes negative, depending on
convenient wording) test.
DiagnosticBuilder kept its implicit conversion operator owing to the
prevalent use of it in return statements.
One bug was found in ExprConstant.cpp involving a comparison of two
PointerUnions (PointerUnion did not previously have an operator==, so
instead both operands were converted to bool & then compared). A test
is included in test/SemaCXX/constant-expression-cxx1y.cpp for the fix
(adding operator== to PointerUnion in LLVM).
llvm-svn: 181869
MSVC provides __wchar_t. This is the same as the built-in wchar_t type
from C++, but it is also available with -fno-wchar and in C.
The commit changes ASTContext to have two different types for this:
- WCharTy is the built-in type used for wchar_t in C++ and __wchar_t.
- WideCharTy is the type of a wide character literal. In C++ this is
the same as WCharTy, and in C it is an integer type compatible with
the type in <stddef.h>.
This fixes PR15815.
llvm-svn: 181587
Add a CXXDefaultInitExpr, analogous to CXXDefaultArgExpr, and use it both in
CXXCtorInitializers and in InitListExprs to represent a default initializer.
There's an additional complication here: because the default initializer can
refer to the initialized object via its 'this' pointer, we need to make sure
that 'this' points to the right thing within the evaluation.
llvm-svn: 179958
This is an optional variant of the CFG. This allows analyses to model whether
or not a static initializer has run, e.g.:
static Foo x = bar();
For basic dataflow analysis in Sema we will just assume that the initializer
always runs. For the static analyzer we can use this branch to accurately
track whether or not initializers are on.
This patch just adds the (opt-in) functionality to the CFG. The
static analyzer still needs to be modified to adopt this feature.
llvm-svn: 178263
Use Optional<CFG*> where invalid states were needed previously. In the one case
where that's not possible (beginAutomaticObjDtorsInsert) just use a dummy
CFGAutomaticObjDtor.
Thanks for the help from Jordan Rose & discussion/feedback from Ted Kremenek
and Doug Gregor.
Post commit code review feedback on r175796 by Ted Kremenek.
llvm-svn: 175938
This is a more natural order of evaluation, and it is very important
for visualization in the static analyzer. Within Xcode, the arrows
will not jump from right to left, which looks very visually jarring.
It also provides a more natural location for dataflow-based diagnostics.
Along the way, we found a case in the analyzer diagnostics where we
needed to indicate that a variable was "captured" by a block.
-fsyntax-only timings on sqlite3.c show no visible performance change,
although this is just one test case.
Fixes <rdar://problem/13016513>
llvm-svn: 174447
Inlining these functions is essential for correctness. We often have
cases where we do not inline calls. For example, the shallow mode and
when reanalyzing previously inlined ObjC methods as top level.
llvm-svn: 174245
Presumably, if the printf format has the sign explicitly requested, the user
wants to treat the data as signed.
This is a fix-up for r172739, and also includes several test changes that
didn't make it into that commit.
llvm-svn: 172762
it apart from [[gnu::noreturn]] / __attribute__((noreturn)), since their
semantics are not equivalent (for instance, we treat [[gnu::noreturn]] as
affecting the function type, whereas [[noreturn]] does not).
llvm-svn: 172691
First check only wrapped with i==8, second wrapped at i==2,8,18,28,...
This fix restores the intended behavior: i==8,18,28,...
Found with -fsanitize=integer.
llvm-svn: 171718
deterministic.
Commit message for r170826:
[analyzer] Traverse the Call Graph in topological order.
Modify the call graph by removing the parentless nodes. Instead all
nodes are children of root to ensure they are all reachable. Remove the
tracking of nodes that are "top level" or global. This information is
not used and can be obtained from the Decls stored inside
CallGraphNodes.
Instead of existing ordering hacks, analyze the functions in topological
order over the Call Graph.
Together with the addition of devirtualizable ObjC message sends and
blocks to the call graph, this gives around 6% performance improvement
on several large ObjC benchmarks.
llvm-svn: 170906
Modify the call graph by removing the parentless nodes. Instead all
nodes are children of root to ensure they are all reachable. Remove the
tracking of nodes that are "top level" or global. This information is
not used and can be obtained from the Decls stored inside
CallGraphNodes.
Instead of existing ordering hacks, analyze the functions in topological
order over the Call Graph.
Together with the addition of devirtualizable ObjC message sends and
blocks to the call graph, this gives around 6% performance improvement
on several large ObjC benchmarks.
llvm-svn: 170826
This paves the road for constructing a better function dependency graph.
If we analyze a function before the functions it calls and inlines,
there is more opportunity for optimization.
Note, we add call edges to the called methods that correspond to
function definitions (declarations with bodies).
llvm-svn: 170825
We still need to do a recursive walk to determine all static/global variables
referenced by a block, which is needed for region invalidation.
llvm-svn: 169481
For most cases where a conversion specifier doesn't match an argument,
we usually guess that the conversion specifier is wrong. However, if
the argument is an integer type and the specifier is %C, it's likely
the user really did mean to print the integer as a character.
(This is more common than %c because there is no way to specify a unichar
literal -- you have to write an integer literal, such as '0x2603',
and then cast it to unichar.)
This does not change the behavior of %S, since there are fewer cases
where printing a literal Unicode *string* is necessary, but this could
easily be changed in the future.
<rdar://problem/11982013>
llvm-svn: 169400
We tried to account for 'uint8_t' by saying that /typedefs/ of 'char'
should be corrected as %hhd rather than %c, but the condition was wrong.
llvm-svn: 169397