| Age | Commit message (Collapse) | Author | Files | Lines |
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
'fix-volatile-simplification', 'struct-asm-ops', 'restricted-pointers', 'fix-f2i-casts', 'symaddr-description', 'flush-stdout' and 'diet-simple' into tip
|
|
ASM operands have the following syntax:
[<ident>] "<constraint>" '(' <expr> ')'
For some reasons, during parsing this is stored
as a sequence of 3 expressions. This has some serious
disadvantages though:
- <ident> has not the type of an expression
- it complicates processing when compared to having a specific
struct for it (need to loop & maintain some state).
- <ident> is optional and stored as a null pointer when not present
which is annoying, for example, if null pointers are used internally
in ptr-lists to mark removed pointers.
Fix this by using a specific structure to store the 3 elements
of ASM operands.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
|
|
It's often the case that we simply need the expr's truth value.
To get the value of an expression or simply if we need to know
if it's a constant value we can use some functions like
get_expression_value() or const_expression_value() depending
on the type of warning needed if the expression is not constant
(for various definition of constant).
However none of these functions take in account the fact that
a comma expression can also have a value known at compile time.
In order to not introduce unwanted change elsewheer in the code,
introduce a new function expr_truth_value() which never warn
but will return -1 if the expr have no known boolean value.
Note: the whole set of functions should be unified to take comma
expressions in account when needed.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Address constants [6.6(9)] constitute one of the types of constant
expressions allowed in initializers [6.6(7)] for static storage
duration objects [6.7.8(4)].
Introduce a new flag for tagging expressions which qualify as
being an address constant.
Make sure not to carry over the address constant attribute from
subexpressions for operators that never yield address constants,
i.e. most arithmetic ones, logical ones etc.
Signed-off-by: Nicolai Stange <nicstange@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Arithmetic constant expressions may be either of (6.6(8)):
- integer constant expressions
- floating point constants
or any arithmetic expression build up from them.
Furthermore, casts with arithmetic destination types preserve
arithmetic constness.
Arithmetic constant expressions may be used as initializers for
objects of static storage duration.
Introduce a new constexpr flag : CEF_ACE.
Modify CEF_SET_ICE and CEF_SET_FLOAT to also include that new bit.
Thus, whenever an integer constant expression or a floating point
constant is recognized, it is automatically tagged as an arithmetic
constant expression.
Note that everything has already been set up such that the new flag
propagates nicely from subexpressions to parent expressions at evaluation.
Signed-off-by: Nicolai Stange <nicstange@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Move the whole calculation of cast expressions' constness flags to the
evaluation phase such that expressions like
(int)__builtin_choose_expr(0, 0, 0)
can now be recognized as qualifying as integer constant expressions.
Signed-off-by: Nicolai Stange <nicstange@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Currently, the expression evaluation code explicitly opts out from
constness at evaluation if certain criteria regarding the subexpressions
are not matched.
Instead of this active opt-out, we want to have subexpression constness
attributes to get propagated from child expressions to their parents in
the future.
A prerequisite is that each expression's ->flags is in a defined
state at all times.
Set ->flags to SET_INT or NONE at expression allocation time,
depending if the expression has a type or not
(alloc_const_expression() or alloc_expression()).
Signed-off-by: Nicolai Stange <nicstange@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
Even if sparse attempted to verify that initializers for static storage
duration objects are constant expressions [6.7.8(4)] (which it
currently does not), it could not tell reliably.
Example:
enum { b = 0 };
static void *c = { (void*)b }; /* disallowed by C99 */
References to enum members are not allowed in address constants [6.6(9)]
and thus, the initializer is not a constant expression at all.
Prepare for a more fine-grained tracking of expression constness in the
sense of C99 [6.4.4, 6.6].
Introduce a broader set of constness tracking flags, resembling the
four types of primary expression constants [6.4.4] (integer, floating,
enumeration, character). Define helper macros to consistently set and
clear these flags as they are not completely independent.
In particular, introduce the following flags for tagging expression constness
at the level of primary expressions:
- CEF_INT: integer constant, i.e. literal
- CEF_FLOAT: floating point constant (former Float_literal flag)
- CEF_ENUM: enumeration constant
- CEF_CHAR: character constant
Introduce the CEF_ICE flag meant for tagging integer constant
expressions. It is equivalent to the former Int_const_expr flag.
Note that CEF_INT, CEF_ENUM and CEF_CHAR flags imply CEF_ICE being set.
Signed-off-by: Nicolai Stange <nicstange@gmail.com>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
|
|
The "trivial fix" is to just save off the offset in check_designators
(add a new field to the "EXPR_IDENTIFIER" part of "struct expression"
and then pick up that offset in "convert_ident()"
However, that has exactly the same issue with the whole fake
EXPR_IDENTIFIER created by "next_designators()". Now we need to
initialize the offset field there too. And, for the same reason as
before, the field that "next_designator()" picks may not *have* an
identifier, because the next designator may in fact be an anonymous
union.
Anyway, with all that said, maybe this really confusing and hacky
patch would work. It passes my tests. The magic offset calculation in
next_designators() has a big comment about what the heck it is doing,
and otherwise it's a fairly straightforward case of "save offset from
check_designators() time to be used by convert_ident()".
My stupid test-case is this incredibly hacky thing:
struct A {
int aa;
int bb;
};
struct S {
int a;
union {
int b;
int c;
} u[10];
int dummy;
union {
int d;
int e;
};
};
int fn(void)
{
struct S s = {
.a = 1,
.u[2].b = 2,
.dummy = 1,
{ 3 }
};
return s.dummy*1000 + s.d*100 + s.u[2].b*10 + s.a; // 1321
}
where I use "./test-linearize" to verify that the initializer layout
matches the code generation layout (so that 'fn' function *should*
linearize to just a simple "ret.32 $1321", and with this patch it
does).
But I bet this misses some case. However, the current state wrt
initializer offsets really is very broken, so maybe it's ok.
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
The old code was relicensed by Novafora Corporation, successor in interest to
Transmeta Corporation, in 2009. Other authors were also asked about the change
of their contributions to the MIT license and all with copyrightable changes
agreed to it.
Signed-off-by: Franz Schrober <franzschrober@yahoo.de>
Acked-by: Adam DiCarlo <adam@bikko.org>
Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
Acked-by: Alberto Bertogli <albertito@blitiri.com.ar>
Acked-by: Alecs King <alecs@perlchina.org>
Acked-by: Alexander Shishkin <alexander.shishckin@gmail.com>
Acked-by: Alexey Dobriyan <adobriyan@gmail.com>
Acked-by: Alexey Zaytsev <alexey.zaytsev@gmail.com>
Acked-by: Andries E. Brouwer <Andries.Brouwer@cwi.nl>
Acked-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Acked-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Acked-by: Ben Pfaff <blp@nicira.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Bernd Petrovitsch <bernd@petrovitsch.priv.at>
Acked-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Acked-by: Blue Swirl <blauwirbel@gmail.com>
Acked-by: Chris Forbes <chrisf@ijw.co.nz>
Acked-by: Chris Wedgwood <cw@f00f.org>
Acked-by: Christopher Li <sparse@chrisli.org>
Acked-by: Damien Lespiau <damien.lespiau@gmail.com>
Acked-by: Dan Carpenter <error27@gmail.com>
Acked-by: Dan McGee <dan@archlinux.org>
Acked-by: Daniel De Graaf <danieldegraaf@gmail.com>
Acked-by: Daniel Sheridan <dan.sheridan@postman.org.uk>
Acked-by: Dave Jones <davej@redhat.com>
Acked-by: David Given <dg@cowlark.com>
Acked-by: David Miller <davem@redhat.com>
Acked-by: David Mosberger-Tang <dmosberger@gmail.com>
Acked-by: David Olien <David.Olien@lsi.com>
Acked-by: Diego Elio Pettenò <flameeyes@flameeyes.eu>
Acked-by: Emil Medve <Emilian.Medve@Freescale.com>
Acked-by: Ethan Jackson <jacksone@nicira.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Frank Zago <fzago@systemfabricworks.com>
Acked-by: Frederic Crozat <fcrozat@suse.com>
Acked-by: Geoff Johnstone <geoff.johnstone@gmail.com>
Acked-by: Hannes Eder <hannes@hanneseder.net>
Acked-by: Jan Pokorný <pokorny_jan@seznam.cz>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Acked-by: Jiri Slaby <jslaby@suse.cz>
Acked-by: Joe Perches <joe@perches.com>
Acked-by: Joel Soete <rubisher@scarlet.be>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Acked-by: Josh Triplett <josh@kernel.org>
Acked-by: Kamil Dudka <kdudka@redhat.com>
Acked-by: Kim Phillips <kim.phillips@linaro.org>
Acked-by: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
Acked-by: Kovarththanan Rajaratnam <kovarththanan.rajaratnam@gmail.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Acked-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Acked-by: Martin Nagy <nagy.martin@gmail.com>
Acked-by: Masatake YAMATO <yamato@redhat.com>
Acked-by: Mauro Dreissig <mukadr@gmail.com>
Acked-by: Michael Büsch <m@bues.ch>
Acked-by: Michael Stefaniuc <mstefani@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Mika Kukkonen <mikukkon@iki.fi>
Acked-by: Mike Frysinger <vapier@gentoo.org>
Acked-by: Mitesh Shah <Mitesh.Shah@synopsys.com>
Acked-by: Morten Welinder <mortenw@gnome.org>
Acked-by: Namhyung Kim <namhyung@gmail.com>
Acked-by: Nicolas Kaiser <nikai@nikai.net>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Pavel Roskin <proski@gnu.org>
Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
Acked-by: Peter Jones <pjones@redhat.com>
Acked-by: Peter A Jonsson <pj@sics.se>
Acked-by: Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
Acked-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Acked-by: Randy Dunlap <rdunlap@xenotime.net>
Acked-by: Reinhard Tartler <siretart@tauware.de>
Ached-by: Richard Knutsson <richard.knutsson@gmail.com>
Acked-by: Rob Taylor <rob.taylor@codethink.co.uk>
Acked-by: Rui Saraiva <rmpsaraiva@gmail.com>
Acked-by: Ryan Anderson <ryan@michonline.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Acked-by: Samuel Bronson <naesten@gmail.com>
Acked-by: Santtu Hyrkkö <santtu.hyrkko@gmail.com>
Acked-by: Shakthi Kannan <shakthimaan@gmail.com>
Acked-by: Stephen Hemminger <shemminger@linux-foundation.org>
Acked-by: Thomas Schmid <Thomas.Schmid@br-automation.com>
Acked-by: Tilman Sauerbeck <tilman@code-monkey.de>
Acked-by: Vegard Nossum <vegardno@ifi.uio.no>
Acked-by: Xi Wang <xi.wang@gmail.com>
Acked-by: Yura Pakhuchiy <pakhuchiy@gmail.com>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
The previous warning about bad constant is actually
mean for variable length array.
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
A follow up change to parse the wide char string.
It currently only parse and store it like normal strings.
Need more change to reflect the base type and size etc.
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Keep storage class (and "is it inline") explicitly in decl_state;
translate to modifiers only when we are done with parsing. That
avoids the need to separate MOD_STORAGE bits while constructing
the type (e.g. in alloc_indirect_symbol(), etc.). It also allows
to get rid of MOD_FORCE for good - instead of passing it to typename()
we pass an int * and let typename() tell whether we'd got a force-cast.
Indication of force-cast never makes it into the modifier bits at all.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <chrisl@hera.kernel.org>
|
|
Doing lookup_symbol() with NS_TYPEDEF will happily skip the redeclarations
of the same identifier with NS_SYMBOL. We need to check that we are not
dealing with something like
typedef int T;
void f(int T)
{
static T a; /* not a valid declaration - T is not a typedef name */
or similar (e.g. enum member shadowing a typedef, etc.).
While we are at it, microoptimize similar code in lookup_type() - instead
of sym->namespace == NS_TYPEDEF we can do sym->namespace & NS_TYPEDEF;
the former will turn into "fetch 32bit value, mask all but 9 bits, compare
with NS_TYPEDEF", the latter - "check that one bit in 32bit value is set".
We never mix NS_TYPEDEF with anything in whatever->namespace, so the
tests are equivalent.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Christopher Li <sparse@chrisli.org>
|
|
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
expression.h didn't work if included alone, before any other headers; fix that
by having it include the headers it needs.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
|
|
Turn FORCE_MOD into storage class specifier (that's how it's
actually used and that makes for much simpler logics).
Introduce explicit EXPR_FORCE_CAST for forced casts; handle it
properly.
Kill the idiocy in get_as() (we end up picking the oddest things
for address space - e.g. if we have int __attribute__((address_space(1))) *p,
we'll get warnings about removal of address space when we do things like
(unsigned short)*p. Fixed. BTW, that had caught a bunch of very odd
bogosities in the kernel and eliminated several false positives in there.
As the result, get_as() is gone now and evaluate_cast() got simpler.
Kill the similar idiocy in handling pointer assignments; while we are at it,
fix the qualifiers check for assignments to/from void * (you can't assign
const int * to void * - qualifiers on the left side should be no less than
on the right one; for normal codepath we get that checked, but the special
case of void * skips these checks).
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
AFAICS, that should do null pointer constants right. We assign
special instance of void * (&null_ctype) to (void *)<zero integer
constant expression> and replace it with normal void * when we
don't want null pointer constant. is_zero_constant() checks if
we have an integer constant expression, does conservative expand
(i.e. instead of generating an error on 1/0, etc. leaves the
node unreplaced) and checks if we have reduced the sucker to
EXPR_VALUE[0] without comma taint.
Implemented all (AFAICS) special cases involving null pointer
constants; most changes in evaluate_compare() and evaluate_conditional().
Both are still incomplete; handling of qualifiers is still missing,
but that's a separate story.
Note that we get two new sets of warnings on the kernel build; one is
due to wrong size_t (handled in the next patch; didn't show up until
now since we didn't warn on comparison of pointers to incompatible
types) and another is a pile of warnings about integer 0 used as NULL
on
if (p == 0)
where p is a pointer. Additionally, there's an idiotic
(p>0)
in one place (again, p is a pointer). Bugger if I know how gcc doesn't
warn on that one, it's certainly a standard violation and bloody pointless
even as extension...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
Treat it as normal binary operation, taint the value, check the taint.
We can do other kind of value tainting with the same infrastructure
as well...
Review and testing would be welcome; AFAICS, it works, but...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
Hopefully correct handling of integer constant expressions. Please, review.
Rules:
* two new flags for expression: int_const_expr and float_literal.
* parser sets them by the following rules:
* EXPR_FVALUE gets float_literal
* EXPR_VALUE gets int_const_expr
* EXPR_PREOP[(] inherits from argument
* EXPR_SIZEOF, EXPR_PTRSIZEOF, EXPR_ALIGNOF get int_const_expr
* EXPR_BINOP, EXPR_COMPARE, EXPR_LOGICAL, EXPR_CONDITIONAL,
EXPR_PREOP[+,-,!,~]: get marked int_const_expr if all their
arguments are marked that way
* EXPR_CAST gets marked int_const_expr if argument is marked
that way; if argument is marked float_literal but not
int_const_expr, we get both flags set.
* EXPR_TYPE also gets marked int_const_expr (to make it DTRT
on the builtin_same_type_p() et.al.)
* EXPR_OFFSETOF gets marked int_const_expr
When we get an expression from parser, we know that having int_const_expr on
it is almost equivalent to "it's an integer constant expression". Indeed,
the only checks we still have not done are that all casts present in there
are to integer types, that expression is correctly typed and that all indices
in offsetof are integer constant expressions. That belongs to evaluate_expression()
and is easily done there.
* evaluate_expression() removes int_const_expr from some nodes:
* EXPR_BINOP, EXPR_COMPARE, EXPR_LOGICAL, EXPR_CONDITIONAL,
EXPR_PREOP: if the node is marked int_const_expr and some
of its arguments are not marked that way once we have
done evaluate_expression() on them, unmark our node.
* EXPR_IMLICIT_CAST: inherit flags from argument.
* cannibalizing nodes in *& and &* simplifications: unmark
the result.
* EXPR_CAST: unmark if we are casting not to an integer type.
Unmark if argument is not marked with int_const_expr after
evaluate_expression() on it *and* our node is not marked
float_literal (i.e. (int)0.0 is fine with us).
* EXPR_BINOP created (or cannibalizing EXPR_OFFSETOF) by
evaluation of evaluate_offsetof() get int_const_expr
if both arguments (already typechecked) have int_const_expr.
* unmark node when we declare it mistyped.
That does it - after evaluate_expression() we keep int_const_expr only if
expression was a valid integer constant expression.
Remaining issue: VLA handling. Right now sparse doesn't deal with those in
any sane way, but once we start handling their sizeof, we'll need to check
that type is constant-sized before marking EXPR_SIZEOF int_const_expr.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
Remaining known problems:
* size of array is still miscalculated in cases with missing braces
* expand still mishandles [0 ... 1].a et.al.
* expand still doesn't deal with overlaps correctly.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
|
|
This removes the list of symbols for block statements, and instead makes
a declaration be a statement of its own.
This is necessary to correctly handle the case of mixed statements and
declarations correctly, since the order of declarations and statements
is meaningful.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
This is what we do for most enums, making it clear
that a zero means "uninitialized", since that easily
happens with our zeroing allocator.
|
|
It's disgusting how intimate lib.c is with all the types,
and this is slowly trying to split things up a bit. Now
the intimate part is in allocate.c, but maybe we can get
to the point where each allocation user just declares its
own allocation strategy, and just uses the generic routines
in allocate.c
|
|
Needed for pointer inc/dec. These things are all supposed to be
all set by the type evaluation phase, so that later parts don't
need to worry.
|
|
Not only do all users want it, the list of used symbols
is not stable until after the tree has been evaluated.
|
|
I used to think I needed it. That's no longer the case: we just
follow the "bit_offset" in the type information.
There may be cases where we inadvertently cast the information
away, and those places will break now, but that's a bug really,
not an excuse for EXPR_BITFIELD.
|
|
This also makes our evaluation simplification only happen
for the implied ones. If you put an explicit cast somewhere,
it does _not_ get combined with an implied one.
|
|
returns the size of the underlying object.
This is different from "sizeof(*expr)" for arrays, where
the array would degenerate to a pointer to one member, and
thus "sizeof(*expr)" gives the size of one entry in the
array.
Why do this? It's useful for things like
#define memset(a,b,c) ({ \
(void) __builtin_warning(__sizeof_ptr__(a) > 1, __sizeof_ptr__(a) != (c), "check memset size"); \
memset(a, b, c); })
where we really want to check the size of the object we're
doing the "memset()" on, but the regular sizeof() just doesn't
cut it.
|
|
positional markers be hierarchical rather than a flat list.
This makes the data structure a bit more complex, but it simplifies
some of the code, and makes it possible to evaluate complex initializers
without going insane.
In particular, we how support
struct xxxx var = {
.a.b[10] = 1;
};
which we couldn't handle at all before (it had to
be written as
struct xxxx var = {
.a = {
.b = { [10] = 1; }
}
}
or similar.
The new code changes all array indexes and structure members
to EXPR_POS expressions offset from the "outer" scope (either
start of the symbol, or an outer EXPR_POS).
|
|
Handling of non-lvalue compound objects:
We introduce a new primitive - EXPR_SLICE. Meaning is "that many bits
from that offset in that non-lvalue struct or union". It is used when
we try to get a member out of a non-lvalue struct or union (subsequent .<field>
just narrow the slice). And as far as scalar, struct and union fields count,
that's it. The only subtle point is handling of array fields. And there
I'm doing what C99 requires - they *do* decay to real, honest pointers,
causing a copy of object to memory if needed. We get an anonymous object
that lives until the next sequence point; optimizer is certainly free to
get rid of it completely if it can make do with the value we'd copied there.
Note that you _are_ allowed to say
foo().a[1] = 0;
It doesn't make sense, since the value you've assigned will be immediately
lost (and any optimizer will turn that into f()), but it is legitimate and
it avoids a *lot* of PITA in describing semantics.
It covers only array decay - any other member of non-lvalue struct or union
is *not* an lvalue and in
struct foo {int x; int y[2];};
struct foo a(void);
...
a().x = 0; /* not allowed, non-lvalue */
a().y[0] = 1; /* allowed, but pointless */
you will get an error from the first assignment, but not from the second
one.
Signed-off-by: Al Viro <viro@parcelfarce.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Make linearize.h show the right ops for the logical (as opposed to
binary) and/or EXPR_BINOP.
|
|
expression.
This is just a very high-level cost, mainly distinguishing
between "safe" and "unsafe" operations, so that we can
determine if we can turn a C conditional into a select
statement, or a logical op into one without short-ciruiting.
|
|
It's the same as a regular C conditional, except you could
evaluate both sides first. Right now we treat it exactly
the same as an EXPR_CONDITIONAL.
|
|
FP handling added, everything straightforward by now.
|
|
This teaches sparse what __alignof__ really means, instead of just using
the same code as "__sizeof__"
It gets rid of the warnings in ebtables that does:
struct ebt_entries {
...
char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)));
};
Which caused warning because sparse was evaluating __alignof__ as the same as sizeof,
and sizeof was 57 (ie non-power of 2).
This is just based on the existing code and a peek at the data
structures in expression and symbol.
|
|
comparisons etc:
if (typeof(a) == int) {
...
(although right now I don't actually do the proper comparison
expansion and all comparisons return "true").
|
|
to look up types.
This makes up get the proper nesting characteristics
in case you mix typedefs and regular symbols with the
same name.
|
|
This doesn't actually get them _right_, but as long as they
end up being constant when used, we at least silently ignore
them until then.
|
|
isn't the sole copyright owner these days.
|
|
in order to see NULL pointer expressions immediately.
We want NULL pointers to be visible as such at type check time,
long before we do the full expansion/simplification phase.
A NULL pointer is a weaker type than a normal (void *), since
it has no context or address space associated with it, for example.
|
|
does type evaluation, the second one does value evaluation
and inline expansion.
This has the advantage that by the time we do value evaluation
and inline expansion, we have traversed the tree fully once,
which allows us to take advantage of function-global information,
ie we know whether symbols have ever been accessed etc.
|
|
This patch removes the type-names on the anonymous structures. This
fixes compilation when using gcc-3.3 (Debian). Credit for identifying
the fix goes to Arnaldo Carvalho de Melo <acme@conectiva.com.br>.
|
|
(&&label) and computed goto (goto *expr).
Add label ctype for __label__ identifier. This is still quite broken
(it should create a block-symbol in the NS_LABEL namespace, right now
it creates a regular symbol).
|
|
not evaluation. We have nasty recursion issues otherwise.
|
|
preparing for a public release.
|
|
the initializer expression list as EXPR_POS expressions so
that a back-end can DTRT.
Show complex initializers now that we've calculated the offsets
of the expressions.
|
|
Use the "used_list" to build up the symbol tree, so that we
automatically get new symbols that get discovered during
evaluation.
|
|
Make the pre-processor use the expression evaluator, so that
it actually gets all the signed/unsigned comparisons right
etc.
Make logical expressions an expression type of their own.
They have some very special behaviour both type-wise and
evaluation-wise (the short-circuiting thing).
|
|
|
|
the real one when it goes out the door.
|
|
(or NULL) rather than just 1 (or 0).
Make "examine_symbol_type()" follow 'typeof's, and return the result.
|
|
expressions, post-op expressions.
Move some of the evaluation functions from test-parsing.c to evaluate.c
|
|
Now constant expressions (strings, integers and fp constants)
are evaluated at parse-time into the proper EXPR_xxx type.
Remove "struct token" from "struct statement", which really only
wanted to know the position. So replace it with "struct position".
|
|
type discovery (initializers are not independent expressions).
|
|
add them to the parse tree. We now do.
|
|
and evaluate their type to be arrays of char rather than just a pointer.
|
|
|
|
to it, instead of having everybody have pointers to "struct token"
only because they wanted to have the position.
Fix array addition type degeneration.
|
|
so that a EXPR_VALUE expression never contains extra bits that
won't be used. It's just less confusing that way (but realize that
we always keep the value unsigned, even if the _type_ is signed).
|
|
Make expr->type be a 'enum expression_type' for nicer
compiler messages.
|
|
Optimize away an offset of 0 in a structure reference.
|
|
even though they parse like other binops: they have different semantic
type behaviour, and should be evaluated separately.
Show bitfield symbol types.
|
|
make the arguments use a proper argument list instead of being
a comma-expression (which has totally different type semantics).
Evaluate assignments and function calls (and their arguments).
Show function calls in the debug info.
|
|
etc. Add a function call expression type. Make expression type
evaluation return a success/failure value.
|
|
the expressions, and turn constant expressions (enums and constant
tokens) into "value expressions" - their actual values.
|
|
left behind in "parse.h" when the files were split.
|
|
proper values.
Make macro re-declaration legal if the new and old
values match.
|
|
its own - expression.c.
|