94 Commits

Author SHA1 Message Date
Chris Lattner
8655428238 factor casts together, add a case for __extension__
llvm-svn: 39620
2007-06-08 22:32:33 +00:00
Chris Lattner
d0f76515f7 add missing case
llvm-svn: 39619
2007-06-08 22:16:53 +00:00
Steve Naroff
98cf3e95ce Bug #:
Submitted by:
Reviewed by:

The following code illustrates a bug in the semantic analysis for assignments:

int func() {
  int *P;
  char *x;
  P = x; // type of this assignment expression should be "int *", NOT "char *".
}

While the type checking/diagnostics are correct, the type of the assignment
expression is incorrect (which shows up during code gen).  With the fix,
the llvm code looks correct...

[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang cast.c -emit-llvm
cast.c:4:5: warning: incompatible pointer types assigning 'char *' to 'int *'
  P = x; // type of assignment expression is "int *", NOT "char *".
  ~ ^ ~
; ModuleID = 'foo'

define i32 @func() {
entry:
        %P = alloca i32*                ; <i32**> [#uses=1]
        %x = alloca i8*         ; <i8**> [#uses=1]
        %allocapt = bitcast i32 undef to i32            ; <i32> [#uses=0]
        %tmp = load i8** %x             ; <i8*> [#uses=1]
        %conv = bitcast i8* %tmp to i32*                ; <i32*> [#uses=1]
        store i32* %conv, i32** %P
        ret i32 undef
}

Even though the fix was simple, I decided to rename/refactor the surrounding code
to make a clearer distinction between constraint checking and conversion.

- Renamed AssignmentConversionResult -> AssignmentCheckResult.
- Renamed UsualAssignmentConversions -> CheckAssignmentConstraints.
- Changed the return type of CheckAssignmentConstraints and CheckPointerTypesForAssignment
from QualType -> AssignmentCheckResult. These routines no longer take a reference to the result (obviously).
- Changed CheckAssignmentOperands to return the correct type (with spec annotations).

llvm-svn: 39601
2007-06-06 18:38:38 +00:00
Chris Lattner
3d01e4eacb On bogus code like this:
int *P2;
  P2(1, 2, 3);

  register short X;
  X();

emit:

ds.c:10:3: error: called object is not a function or function pointer
  P2(1, 2, 3);
  ^~~~~~~~~~~
ds.c:13:3: error: called object is not a function or function pointer
  X();
  ^~~

instead of aborting.

llvm-svn: 39599
2007-06-06 05:14:05 +00:00
Chris Lattner
3343f81a25 Fix semantic analysis of calls on stuff like:
int func() {
 int (*FP)();
 FP();
 (*****FP)();
}

llvm-svn: 39598
2007-06-06 05:05:41 +00:00
Chris Lattner
4347e369b4 implement codegen of string literals.
llvm-svn: 39597
2007-06-06 04:54:52 +00:00
Chris Lattner
1d411a826e add some fixme's for incorrect sema
llvm-svn: 39591
2007-06-05 20:52:21 +00:00
Steve Naroff
71b59a9a29 Bug #:
Submitted by:
Reviewed by:
Fixed an "impurity" in the typechecking code (to more closely model the
C99 spec)...

- Added function Sema::DefaultFunctionArrayConversion(). This is called
by UsualUnaryConversions(). It is also called from several contexts that
don't call for integer promotions (logical negation for expressions, and
while/if/do/for conditions in statements). It is also used in
UsualAssignmentConversions (which is cleaner than the check I was using
before).

- Changed the name from UsualUnaryConversion->UsualUnaryConversions.

- Added comments to the header.

Since several contexts don't call for integer
promotions,

llvm-svn: 39581
2007-06-04 22:22:31 +00:00
Chris Lattner
0c46c5d55a Fix a fixme, produce diagnostics like this:
ds.c:11:16: error: case label does not reduce to an integer constant
  case 0 ? 0 : foo():
       ~~~~~~~~^~~~~

llvm-svn: 39574
2007-06-02 23:53:17 +00:00
Bill Wendling
db4f06ed2c Submitted by: Bill Wendling
Reviewed by: Chris Lattner

- If the LHS and/or RHS is a reference, then see if they're compatible.
  If so, the type is that of the LHS.

llvm-svn: 39568
2007-06-02 23:29:59 +00:00
Chris Lattner
ea3c20b9eb When a function decays into its address, ensure the result type keeps any
typedef information associated with the input.

llvm-svn: 39562
2007-06-02 22:47:04 +00:00
Chris Lattner
be31ed8e88 Correct the type of logical not.
llvm-svn: 39558
2007-06-02 19:11:33 +00:00
Steve Naroff
9992bbab14 Bug #:
Submitted by:
Reviewed by:
- ParseForStatement(): Put back a test/assignment. My removal of
ParseExprStmt() was a bit over zealous:-(thanks to Chris for pointing it out)
- Add assert to VisitDeclStmt().
- Removed an out-of-date FIXME
- Added some curlies for a couple multi-line calls to Diag().

llvm-svn: 39528
2007-05-30 16:27:15 +00:00
Bill Wendling
216423bbd7 Submitted by: Bill Wendling
Comment format changes.

llvm-svn: 39527
2007-05-30 06:30:29 +00:00
Steve Naroff
56faab2d4f Bug #:
Submitted by:
Reviewed by:
- Many tweaks to various diagnostics.
- Fixed some location/range issues.
- Bug fix to Sema::ParseDeclStmt() - error return code is "true", not 0.

llvm-svn: 39526
2007-05-30 04:20:12 +00:00
Steve Naroff
eb9da94d37 Bug #:
Submitted by:
Reviewed by:
Unified the diagnostics for function calls. Since we have range support,
there is no need for including the argument number. Instead, I've made
the diags more expressive by including more type info.

Also improved the indentation of many calls to Diag (which can be 2-3
lines now).

llvm-svn: 39523
2007-05-30 00:06:37 +00:00
Steve Naroff
6f49f5df03 Bug #:
Submitted by:
Reviewed by:
- Finished Sema::ParseReturnStmt(). Still need to tweak ranges.
- Tweaked location for function arguments (they now point at the expression directly, no parens or commas).
- Added InvalidOperands helper...was sick of looking at the same 3 lines in ~9 Check functions.
- Added a few diags and moved a group of statement diags to the proper comment/category.

llvm-svn: 39517
2007-05-29 14:23:36 +00:00
Steve Naroff
3c87a57a2c Bug #:
Submitted by:
Reviewed by:
Add range support to Sema::CheckConditionalOperands().

llvm-svn: 39514
2007-05-28 19:40:22 +00:00
Steve Naroff
8563f65042 Bug #:
Submitted by:
Reviewed by:
Refine Sema::ParseCallExpr() diags (range support, add types).

Before:

func-assign.c:27:11: warning: passing argument 1 from incompatible pointer type
  pintFunc(&FOO);
          ^
func-assign.c:28:12: error: incompatible type for argument 1
  floatFunc(&FOO);
           ^
func-assign.c:29:12: error: too many arguments to function
  floatFunc(1,2,3);
           ^
After:

func-assign.c:27:11: warning: passing incompatible pointer 'struct foo *' to function expecting 'int *'
  pintFunc(&FOO);
  ~~~~~~~~^~~~~
func-assign.c:28:12: error: passing incompatible type 'struct foo *' to function expecting 'float'
  floatFunc(&FOO);
  ~~~~~~~~~^~~~~
func-assign.c:29:12: error: too many arguments to function
  floatFunc(1,2,3);
  ~~~~~~~~~^  ~

llvm-svn: 39513
2007-05-28 19:25:56 +00:00
Steve Naroff
758ada12f4 Bug #:
Submitted by:
Reviewed by:
- Implement FIXME in Sema::CheckIndirectionOperand().
- Added "const" to FunctionDecl::getResultType().

llvm-svn: 39512
2007-05-28 16:15:57 +00:00
Chris Lattner
eefa10e78a implement full sema support for the GCC address-of-label extension.
llvm-svn: 39510
2007-05-28 06:56:27 +00:00
Steve Naroff
9358c715da Bug #:
Submitted by:
Reviewed by:
- Added type checking to Sema::ParseReturnStmt (still under construction).
- Improved Expr::isLvalue() and Expr::isModifiableLvalue() to return more
info. Used the info in Sema::CheckAssignmentOperands() to produce more
descriptive diagnostics. Added FIXME to other clients of isLvalue()/etc.
- Added a SourceLocation slot to MemberExpr...changed the implementation
of getSourceRange().
- Added getResultType() helper to FunctionDecl.
- Changed many Diag calls to use the SourceRange support (now that it's
a big hit...we better milk it:-).

llvm-svn: 39501
2007-05-27 23:58:33 +00:00
Steve Naroff
7fd6893333 Bug #:
Submitted by:
Reviewed by:
One bug compiling "Carbon.h" on Leopard, one diagnostic tweak.
- CheckIndirectionOperand wasn't operating on the canonical type (so it
was complaining about typedef names).
- The diagnostic was less than great. Here's what is was:

[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang t.c
t.c:4:3: error: invalid argument type to unary expression 'int'
 *p;
 ^~

And here's what I changed it to...

snaroff:clang naroff$ ../../Debug/bin/clang bug.c
bug.c:5:3: error: indirection requires a pointer ('int' operand invalid)
  *p;
  ^~

llvm-svn: 39481
2007-05-22 18:27:41 +00:00
Chris Lattner
67ca9252f8 Implement Sema::ParseNumericConstant for integer constants in terms of APInt
and correctly in terms of C99 6.4.4.1p5.

llvm-svn: 39473
2007-05-21 01:08:44 +00:00
Steve Naroff
30d1fbc803 Bug #:
Submitted by:
Reviewed by:
Bozo bug in last checkin. Needed to move the check for null pointers
up (and out of the pointer/pointer clause).

llvm-svn: 39466
2007-05-20 19:46:53 +00:00
Steve Naroff
ada7d4298b Bug #:
Submitted by:
Reviewed by:
Fix two bugs...

- Sema::CheckConditionalOperands(). Needed to move the check for
null pointer constants up to the clause dealing with two pointers types.
The previous code would never get executed.
- Expr::isNullPointerConstant(). This predicate was much too naive...it
should have had a FIXME (my bad). It now deals with "void *" cast expressions.
It still has one major bug...it needs to evaluate the expression to correctly
determine if it is a null pointer constant (e.g. 7-7 should pass).

llvm-svn: 39464
2007-05-20 17:54:12 +00:00
Chris Lattner
84e160a7a8 fix some indentation funkiness
llvm-svn: 39457
2007-05-19 07:03:17 +00:00
Steve Naroff
71ce2e061d Bug #:
Submitted by:
Reviewed by:
An important, but truly mind numbing change.

Added 6 flavors of Sema::Diag() that take 1 or two SourceRanges. Considered
adding 3 flavors (using default args), however this wasn't as clear.

Removed 2 flavors of Sema::Diag() that took LexerToken's (they weren't used).

Changed all the typechecking routines to pass the appropriate range(s).

Hacked the diagnostic machinery and driver to acccommodate the new data.

What's left? A FIXME in clang.c to use the ranges. Chris offered to do the
honors:-) Which includes taking us to the end of an identifier:-)

llvm-svn: 39456
2007-05-18 22:53:50 +00:00
Steve Naroff
e845e272ba Bug #:
Submitted by:
Reviewed by:
More tweaks to error diagnostics (adding types, using the new hooks on expr).
Still more to do...

llvm-svn: 39455
2007-05-18 01:06:45 +00:00
Steve Naroff
53f07dc54d Bug #:
Submitted by:
Reviewed by:
Refinements to the SourceRange/SourceLocation work.

- Renamed Expr::getSourceLocation() helper function to getLocStart(). Added
Expr::getLocEnd(). Converted all the getSourceRange() methods to use the new helpers.
- Removed many getSourceLocation() accessors. The Expr::getLocStart() helper
is the "right" way to get a source location. If we want to add class specific
getters (for location), then the names should be reflective of the specific class.
For examaple, UnaryOperator::getOpLocation(). For now, I see no reason to have these.
- Fixed StringLiteral.
- Start actually instantiating ParenExpr()!

llvm-svn: 39453
2007-05-17 21:49:33 +00:00
Steve Naroff
509fe025aa Bug #:
Submitted by:
Reviewed by:
- Added a getSourceRange() method to all subclasses of Expr.
- Changed all the constructors and instantiators.
- Only added SourceLocations's when necessary. For example, binary
expression *don't* carry the operator location...it isn't
necessary to implement getSourceRange(). On the other hand, unary
expressions *do* carry the operator location.
- Added trivial SourceRange value class to SourceLocation.

Note: need to talk to Chris about the FIXME for StringLiteral...
llvm-svn: 39452
2007-05-17 01:16:00 +00:00
Steve Naroff
a78fe7e3ed Bug #:
Submitted by:
Reviewed by:
- Implement type checking for Sema::CheckConditionalOperands.
- Fixed crasher in Sema::UsualUnaryConversion (incorrect use of cast<>).
- Added a few diagnostics and started passing 2 args! (Thanks Chris!).

Here's some diagnostic output that is much nicer than gcc...

[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang cond.c
cond.c:12:14: error: used type 'struct foo' where arithmetic or pointer type is required
  result = s ? 1 : 2;
             ^
cond.c:13:14: error: incompatible operand types ('struct foo' and 'struct bar')
  result = a ? s : s2;
             ^
cond.c:14:14: warning: pointer type mismatch ('struct foo *' and 'struct bar *')
  result = a ? ps : ps2;
             ^
cond.c:14:10: warning: assignment makes integer from pointer without a cast
  result = a ? ps : ps2;
         ^
cond.c:15:14: error: incompatible operand types ('struct foo *' and 'struct foo')
  result = a ? ps : s;
             ^
cond.c:16:14: warning: pointer type mismatch ('void (*)(int)' and 'void (*)(int, int)')
  result = a ? func : func2;
             ^
cond.c:16:10: warning: assignment makes integer from pointer without a cast
  result = a ? func : func2;
         ^
7 diagnostics generated.
[dylan:~/llvm/tools/clang] admin% cc -c cond.c
cond.c: In function 'main':
cond.c:12: error: used struct type value where scalar is required
cond.c:13: error: type mismatch in conditional expression
cond.c:14: warning: pointer type mismatch in conditional expression
cond.c:14: warning: assignment makes integer from pointer without a cast
cond.c:15: error: type mismatch in conditional expression
cond.c:16: warning: pointer type mismatch in conditional expression
cond.c:16: warning: assignment makes integer from pointer without a cast

llvm-svn: 39451
2007-05-16 19:47:19 +00:00
Chris Lattner
c04bd6ae32 Remove the Sema::Diag helper that takes a type. Convert clients to use
the version that takes a string.

llvm-svn: 39450
2007-05-16 18:09:54 +00:00
Chris Lattner
3dc3d775fb Rename type::getAsString to getAsStringInternal. Add a new
QualType::getAsString() that returns a string, which is much easier
for clients to use.  Convert clients to use it.

llvm-svn: 39449
2007-05-16 18:07:12 +00:00
Steve Naroff
f8a28c5379 Bug #:
Submitted by:
Reviewed by:
- Unified isConstantExpr/isIntegerConstantExpr by creating a private function
named isConstantExpr (that takes a bool to indicate the flavor). isConstantExpr
and isIntegerConstantExpr are now inline wrapper/helper functions.
- Fixed bug in expression based sizeof (it needed to make sure the type is constant).
- Added Sema::CheckConditionalOperands() stub. Will add contraints in my next commit.

llvm-svn: 39446
2007-05-15 20:29:32 +00:00
Steve Naroff
043d45da72 Bug #:
Submitted by:
Reviewed by:
- Completed Expr::isConstantExpr() and Expr::isIntegerConstantExpr().
- Completed Sema::ParseUnaryOp(), it lacked support for sizeof/alignof.
- Added Sema::CheckSizeOfAlignOfOperand(), used by ParseUnaryOp/ParseSizeOfAlignOfTypeExpr.
- Fixed a couple bugs in CheckRelationalOperands/CheckEqualityOperands (make sure extensions aren't treated as errors).
- Changed a bunch of predicates (in BinaryOperator/UnaryOperator) to member functions (the static members weren't being used).
- Added UnaryOperator::isIncrementDecrementOp/isSizeOfAlignOfOp.

llvm-svn: 39445
2007-05-15 02:32:35 +00:00
Steve Naroff
5dd642eb4a Bug #:
Submitted by:
Reviewed by:
Some minor cleanup (comments, spec refs, simplied some expressions).

llvm-svn: 39444
2007-05-14 18:14:51 +00:00
Steve Naroff
475cca0d1a Bug #:
Submitted by:
Reviewed by:
Fixed a bug in Sema::CheckAddressOfOperand(). It was (incorrectly) using
isModifiableLvalue() instead of isLvalue(). This motivated me to (finally)
cleanup methods surrounding lsLvalue/isModifiableLvalue. Cleanup involved:
- adding Expr::isLvalue().
- modified Expr::isModifiableLvalue() to use Expr::isLvalue().
- removed Type::isLvalue(), Type::isModifiableLvalue(), and
QualType::isModifiableLvalue(). They were confusing...the respective logic
is now a part of the Expr member functions...
- also added some comments and spec references, since these methods are
so central to expressions working properly.

llvm-svn: 39443
2007-05-14 17:19:29 +00:00
Steve Naroff
094046fdfc Bug #:
Submitted by:
Reviewed by:
Two bug fixes to CheckIncrementDecrementOperand:
- removed "constantOne" usage and simply use Context.IntTy.
- fix the last constraint check...the lvalue test needs to be on the
expression, not the type! (duh).

llvm-svn: 39442
2007-05-13 03:21:25 +00:00
Steve Naroff
3f59729549 Bug #:
Submitted by:
Reviewed by:
This check-in should finally "nail" complex pointer assignments (involving
qualifiers, etc.).
- Replaced pointerTypeQualifiersAlign() with CheckPointerTypesForAssignment()
This also simplified UsualAssignmentConversions().
- Fixed Type::pointerTypesAreCompatible() and Type::typesAreCompatible()
to closely reflect the spec. They were (unfortunately) compensating for some of the
missing logic in the assignment checking code.

llvm-svn: 39440
2007-05-11 22:18:03 +00:00
Steve Naroff
1f4d72724e Bug #:
Submitted by:
Reviewed by:
- Enhanced UsualAssignmentConversions() to properly handle type qualifiers on
pointers.
- Added helper function Sema::pointerTypeQualifiersAlign().
- Noticed several errors improperly named "ext_" (fixed).
- Combined structureTypesAreCompatible/unionTypesAreCompatible into
tagTypesAreCompatible.
- Renamed Type::getCanonicalType() to Type::getCanonicalTypeInternal(). It
will never confuse/bite me again:-)
- Added a couple extension diagnostics for discarded type qualifiers.

llvm-svn: 39439
2007-05-11 04:00:31 +00:00
Steve Naroff
b8c289df7a Bug #:
Submitted by:
Reviewed by:
Fix a couple bugs in ParseCallExpr().
- check isVariadic().
- make sure an AST isn't created if the number of args don't match but the
types do!
- rename "n" to something more descriptive:-)

llvm-svn: 39438
2007-05-08 22:18:00 +00:00
Steve Naroff
35d8515be7 Bug #:
Submitted by:
Reviewed by:
- Unified CheckSimpleAssignmentOperands/CheckCompoundAssignmentOperands
into one function, named CheckAssignmentOperands. One less function to maintain.
- Converted the unary check functions (ParseUnaryOp and friends) to have
the same API as their binary counterparts.
- Implemented CheckIndirectionOperand (was stubbed). While testing, noticed
that Expr::isModifiableLvalue was incomplete (fixed and referenced draft).
- Added constantOne instance variable to Sema.
- Removed CheckArithmeticOperand (the code was so simple that it is now
part of ParseUnaryOp). The name wasn't great anyway:-)

llvm-svn: 39435
2007-05-07 00:24:15 +00:00
Steve Naroff
218bc2b32d Bug #:
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).

This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).

For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,

<   ExprResult CheckAdditiveOperands( // C99 6.5.6
<     Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);

>   inline QualType CheckAdditionOperands( // C99 6.5.6
>     Expr *lex, Expr *rex, SourceLocation OpLoc);
>   inline QualType CheckSubtractionOperands( // C99 6.5.6
>     Expr *lex, Expr *rex, SourceLocation OpLoc);

While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.

Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)

Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).

llvm-svn: 39433
2007-05-04 21:54:46 +00:00
Steve Naroff
17f76e04d2 Bug #:
Submitted by:
Reviewed by:
Work on finishing up typechecking for simple assignments (=) and function
calls. Here is an overview:
- implemented type checking for function calls (in Sema::ParseCallExpr).
- refactored UsualAssignmentConversions to return the result of the conversion.
This enum will allow all clients to emit different diagnostics based on context.
- fixed bug in Expr::isLvalue()...it wasn't handling arrays properly. Also
changed the name to isModifiableLvalue, which is consistent with the function on QualType.
- Added 6 diagnostics (3 errors, 3 extensions).

llvm-svn: 39432
2007-05-03 21:03:48 +00:00
Steve Naroff
b891de392c Bug #:
Submitted by:
Reviewed by:
More refinements to UsualAssignmentConversions(). Added a call
to do the UsualUnaryConversion for arrays/functions. I believe this is
correct (but subtle). This enabled me to remove code for dealing with
arrays/functions explictly (which more closely reflects the spec).

llvm-svn: 39431
2007-05-02 23:51:10 +00:00
Steve Naroff
9eb2465aeb Bug #:
Submitted by:
Reviewed by:
Refactored assignment conversion code.

- added Sema::UsualAssignmentConversions(). It will service simple
assignment, argument passing, initialization, and return.
- simplified Sema::CheckAssignmentOperands() using the previous function.

llvm-svn: 39429
2007-05-02 21:58:15 +00:00
Steve Naroff
38a9dae33f Bug #:
Submitted by:
Reviewed by:
- implement Type::functionTypesAreCompatible().
- fix bug in Sema::CheckAssignmentOperands(). Spec allows any pointer type
to be assigned to _Bool.

llvm-svn: 39428
2007-05-02 19:22:16 +00:00
Steve Naroff
dd92b932e0 Bug #:
Submitted by:
Reviewed by:
Implement CheckAssignmentOperands(). This includes...

- Adding 6 static member predicates to Type.
- Adding 2 error diagnostics and 3 GCC extensions.
- Adding a "getValue" accessor to IntegerLiteral.

Still more work to do (including implement compound assignments).

llvm-svn: 39427
2007-05-02 02:47:33 +00:00
Steve Naroff
0af9120905 Bug #:
Submitted by:
Reviewed by:
- Disabled -pedantic for now (until it ignores system headers).
- Removed convertSignedWithGreaterRankThanUnsigned() and convertFloatingRankToComplexType().
The logic is now inlined in maxIntegerType and maxComplexType().
- Removed getIntegerRank/getFloatingRank from the private interface. These
are now really private helpers:-)
- Declare maxIntegerType/maxFloatingType static. maxComplexType const.
- Added an enum for the floating ranks.
- Several fixed to getIntegerRank: add Bool, Char, and a clause for enums.

llvm-svn: 39421
2007-04-27 21:51:21 +00:00