Added extensions (subclasses) to the StmtVisitor class that
are useful for dataflow analysis: CFGStmtVisitor and DataflowStmtVisitor.
CFGStmtVisitor is the same as StmtVisitor is that it has separate visitors
for "root" statements in a CFGBlock (statements that have a designated
slot int the list of statements in a CFGBlock). It also recognizes statements
that have implicit control-flow, and calls special visitor methods for those.
DataflowStmtVisitor extends CFGStmtVisitor to serve as a template for
implementing transfer functions. It does a pre-/post-order traversal of
substatements depending on whether we are doing a forward/backward analysis.
It also has special handling for implicit-control-flow statements so that
they are visited only once.
Hartmut Kaiser [Wed, 12 Sep 2007 15:39:04 +0000 (15:39 +0000)]
Removed clang solution file for VC++, which didn't work properly because of hard coded paths in the llvm project files.
Changed windows detection to use LLVM pp constant.
Steve Naroff [Wed, 12 Sep 2007 14:07:44 +0000 (14:07 +0000)]
Fix the following bug submitted by Ted Kremenek:
void func() {
int xx = xx; // incorrectly diagnosed 'xx' as an undeclared identifier.
}
This smallish bug resulted in a largish fix. Here are some highlights:
- Needed to make sure ParseDeclarator is called *before* parsing any
initializer. Removed the "Init" argument to ParseDeclarator.
- Added AddInitializerToDecl() to the Action & Sema classes.
In Sema, this hook is responsible for validating the initializer and
installing it into the respective decl.
- Moved several semantic checks from ParseDeclarator() to
FinalizeDeclaratorGroup(). Previously, this hook was only responsible for
reversing a list. Now it plays a much larger semantic role.
All of the above changes ended up simplifying ParseDeclarator(), which
is goodness...
This method is used to determine if an expression contains implicit
control-flow, and thus appears in a distinct statement slot in the CFG.
For example:
(1) x = ... ? ... ? ...
logically becomes:
(1) ... ? ... : ... (a unique statement slot for the ternary ?)
(2) x = [E1] (where E1 is actually the ConditionalOperator*)
A client of the CFG, when walking the statement at (2), will encounter
E1. In this case, hasImplicitControlFlow(E1) == true, and the client
will know that the expression E1 is explicitly placed into its own statement
slot to capture the implicit control-flow it has.
Fixed bug where ternary expressions and GCC-style conditional expressions
where not reversing the order of their subexpression blocks.
Added feature where CallExprs are placed in their own statement slot in
a CFGBlock. Thus we have a designated "return site" within a CFGBlock when
reasoning about function calls.
Steve Naroff [Tue, 11 Sep 2007 21:17:26 +0000 (21:17 +0000)]
- Add an ObjcIvarDecl AST node (a subclass of FieldDecl).
- Instantiate the node in Sema::ParseField(), based on the type of the TagDecl.
- Add Sema::ObjcAddInstanceVariable(), responsible for adorning/adding the ObjcIvarDecl.
For looking at "dead stores" in declarations, we now check to see
if the assigned value is a constant expression, e.g.:
int x = 0;
We then check to see if "x" is ever reassigned later. If so, we don't
emit a warning. This is because programmers frequently use defensive
programming to make sure a variable has a defined value.
Steve Naroff [Mon, 10 Sep 2007 22:17:00 +0000 (22:17 +0000)]
Fix the following bug submitted by Justin Handville.
int main(int argc, char* argv[])
{
return 0;
}
After speaking briefly with Chris, we decided this should be a front-end fix.
The fix...have Sema::GetTypeForDeclarator() do the default function/array conversion, as
I outlined in the 9/9 email on this topic.
Since this conversion is done before Sema::ParseParamDeclarator(), I thought I could
remove the conversion from Sema::ParseParamDeclarator(). Unfortunately, this didn't work.
The conversion apparently needs to be done in both places (which doesn't make sense to me).
Refactored driver options that perform analyses/work over CFGs to use
"CFGVisitor", which now handles all the boilerplate for iterating over
the function definitions in a translation unit and building the CFGs.
This logic was previously replicated for each driver option that used
CFGs.
The options -dump-cfg, -view-cfg, -check-dead-stores, and
-dump-live-variables now use this refactored code.
Added more checking in "dead stores" for values that are initialized
but never used.
Fix a bug in LiveVariables where uses on the LHS of self-assign
operators (e.g +=, *=, etc) would not be properly recorded in the
liveness state of the variable.
Minor bug fixes to corner cases where LiveVariables would crash on some CFGs
that contained no declarations, or when a variable is declared but never used.
Added "Dead Stores", a flow-sensitive checker that checks for stores
to variables that are no longer live. This analysis is built on top
of CFGs and the LiveVariables analysis.
changes to driver:
added driver option "-check-dead-stores" to run the analysis
Steve Naroff [Thu, 6 Sep 2007 21:24:23 +0000 (21:24 +0000)]
The goal of this commit is to get just enough Sema support to recognize Objective-C classes
as types. That said, the AST nodes ObjcInterfaceDecl, ObjcInterfaceType, and ObjcClassDecl are *very*
preliminary.
The good news is we no longer need -parse-noop (aka MinimalActions) to parse cocoa.m.
Added an early implementation of Live-Variables analysis built on
source-level CFGs. This code may change significantly in the near
future as we explore different means to implement dataflow analyses.
Added a driver option, -dump-live-variables, to view the output of
live variable analysis. This output is very ALPHA; it will be improved shortly.
1. Fix parsing of method prototype involving c-style argument declarations.
2. Fixes all allowable key-words used as selectors.
3. Template to do the messaging parse.
4. A test case for all allowable selector names.
Steve Naroff [Tue, 4 Sep 2007 02:20:04 +0000 (02:20 +0000)]
More fun with initializers!
- Fixed many bugs, enhanced test case considerably, added a diagnostic, etc.
- Refactored CheckInitList() into CheckVariableInitList()/CheckConstantInitList().
- Added CheckInitExpr().
- Support for multi-dimensional arrays looking good.
Steve Naroff [Sun, 2 Sep 2007 02:04:30 +0000 (02:04 +0000)]
Start implementing semantic analysis for C initializers.
Step 1: Start instantiating InitListExpr's.
Step 2: Call newly added function Sema::CheckInitializer() from Sema::ParseDeclarator().
Step 3: Give InitListExpr's a preliminary type.
Step 4: Start emitting diagnostics for simple assignments.
Note:
As a result of step 1, the CodeGen/mandel.c test asserts "Unimplemented agg expr!", which is expected.
As a result of step 4, the test below now fails. This isn't expected and needs to be investigated (it appears type checking for C++ references is flawed in some way).
******************** TEST 'Sema/cxx-references.cpp' FAILED! ********************
Command:
clang -fsyntax-only Sema/cxx-references.cpp
Output:
Sema/cxx-references.cpp:8:12: warning: incompatible pointer types assigning 'int &*' to 'int *'
int *p = &r;
^~
Sema/cxx-references.cpp:10:20: error: incompatible types assigning 'int (int)' to 'int (&)(int)'
int (&rg)(int) = g;
^
Sema/cxx-references.cpp:13:18: error: incompatible types assigning 'int [3]' to 'int (&)[3]'
int (&ra)[3] = a;
^
Sema/cxx-references.cpp:16:14: error: incompatible types assigning 'int *' to 'int *&'
int *& P = Q;
^
4 diagnostics generated.
******************** TEST 'Sema/cxx-references.cpp' FAILED! ********************
Ted Kremenek [Fri, 31 Aug 2007 21:30:12 +0000 (21:30 +0000)]
Added "PrinterHelper" interface (include/AST/PrinterHelper) that can
be passed as an (optional) argument to StmtPrinter to customize
printing of AST nodes.
Used new PrinterHelper interface to enhance printing and visualization
of CFGs. The CFGs now illustrate the semantic connectives between
statements and terminators, wheras in the previous printing certain
expressions would (visible) be printed multiple times to reflect which
expressions used the results of other expressions.
The end result is that the CFG is easier to read for flow of
expression values (following principles similar to the LLVM IR).
Steve Naroff [Fri, 31 Aug 2007 17:20:07 +0000 (17:20 +0000)]
Removed Sema::VerifyConstantArrayType(). With the new Array/ConstantArray/VariableArray nodes, this
routine was causing more trouble than it was worth. Anders/Chris noticed that it could return an error code
without emiting a diagnostic (which results in an silent invalid decl, which should *never* happen). In addition,
this routine didn't work well for typedefs and field decls. Lastly, it didn't consider that initializers aren't
in place yet.
Added Type::getAsConstantArrayType(), Type::getAsVariableArrayType(), Type::getAsVariablyModifiedType(),
and Type::isVariablyModifiedType();
Modified Sema::ParseDeclarator() and Sema::ParseField() to use the new predicates. Also added a FIXME for
the initializer omission. Also added a missing test for "static" @ file scope.
Chris Lattner [Fri, 31 Aug 2007 04:44:06 +0000 (04:44 +0000)]
Implement codegen support for lowering "library builtins" like __builtin_isinf
to their corresponding library routines (e.g. isinf). This allows us to handle
all the stuff in macos math.h, and other stuff as it's added to *Builtins.def.
Steve Naroff [Thu, 30 Aug 2007 22:35:45 +0000 (22:35 +0000)]
Final phase of array cleanup (for now), removing a FIXME from yesterday.
Moved several array constraints checks from Sema::VerifyConstantArrayType() to
Sema::GetTypeForDeclarator(). VerifyConstantArrayType() is now very simple, and
could be removed eventually.
Now, we get the following (correct) messages for BlockVarDecls:-)
[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang x.c -pedantic
x.c:4:20: error: size of array has non-integer type 'float'
int size_not_int[f];
^
x.c:5:21: error: array size is negative
int negative_size[1-2];
^~~
x.c:6:17: warning: zero size arrays are an extension
int zero_size[0];
^
3 diagnostics generated.
Ted Kremenek [Thu, 30 Aug 2007 18:48:11 +0000 (18:48 +0000)]
Fixed a bug in constructing CFG blocks for case statement fall-through
introduced by moving "CaseStmt" pointers out of the list of statements
and into the explicit "label" associated with a CFGBlock. --This
line, and those below, will be ignored--