Custom Query (146 matches)
Results (70 - 72 of 146)
Ticket | Owner | Reporter | Resolution | Summary |
---|---|---|---|---|
#256 | fixed | New Clause Node for Statements | ||
Description |
For whatever reason, statements seem to have some cases where a child node is needed but it isn't its own statement. This problem has either been solved by making them their own statement anyways (such as the FinallyStmt?) or by packing a lot of data structures into one node (such as the WaitForStmt?). The first solution (pretend it is a statement) does work as long as there are no mistakes confusing this node for a statement and none of the special machinery around statements is activated. There are also some speed and memory advantages but they are very small. The second solution (make it all one node) requires a lot more manual work and introduces more special cases. A lot of that has already been done but new cases keep coming up.
The new solution is to add a new super node to // Represents a significant section of a statement. class Clause : public ParseNode { public: Clause( const CodeLocation & loc ) : ParseNode(loc) {} Clause( const Clause & o ) : ParseNode( o ) {} const Clause * accept( Visitor & v ) const override = 0; private: Clause * clone() const override = 0; MUTATE_FRIEND }; All the new "Clause" types inherit from this node and could be given a new suffix. It inherits from ParseNode? so get a code location for debugging and error messages. Also the child clauses could inherit directly from ParseNode? but this helps with organization. A similar solution could be used with expressions/Expr and declarations/Decl, but it just hasn't come up and even if it did there is less special cases around Expr and Decl as compared to Stmt, so the improvements would be fewer. (This might be pushed back to after the old AST is removed to that maintaining symmetry between the new and old AST is not a factor in the rework.) |
|||
#266 | fixed | Increment hoisted outside the loop | ||
Description |
In the following code: forall(T&) struct A { T * next; }; struct B { A(B) link; }; void baz() { for(B ** it;;it = &(*it)->link.next) {} } The for loop is codegened as: void _X3bazFv___1(){ { struct B **_X2itPPS1B_3; struct B **_dtype_static_member_245 = ((struct B **)(&(*(*_X2itPPS1B_3))._X4linkS1A_S1B__1._X4nextPY12__T_generic__1)); for (;;((void)(_X2itPPS1B_3=_dtype_static_member_245))) { } } } This moves the loop increment outside the actual loop, which causes infinite loops. The problem is probably either in Instantiate Generic pass or in the Pass visitor.
Instantiate Generic is the pass creating the variable It could also be because the pass visitor needs to handle stmts_to_add better in this case. |
|||
#286 | fixed | typeof Decays Array Types | ||
Description |
C (and hence CFA) does have a habit of replacing arrays with pointers. However there are a few places it should not be decomposed and one of those is inside a typeof. In some cases this does appear to be happening. I did some simple checks inside sizeof (and repeated them in alignof, but they just play out exactly the same) that looks like this: char array[2]; _Static_assert(sizeof(char[2]) == 2 * sizeof(char)); _Static_assert(sizeof(typeof(char[2])) == 2 * sizeof(char)); _Static_assert(sizeof(array) == 2 * sizeof(char)); _Static_assert(sizeof(typeof(array)) == 2 * sizeof(char)); _Static_assert(alignof(char[2]) == alignof(char)); _Static_assert(alignof(typeof(char[2])) == alignof(char)); _Static_assert(alignof(array) == alignof(char)); _Static_assert(alignof(typeof(array)) == alignof(char)); The first two cases, where we examine the type directly, play out as you would expect, when translation is done the wrapped type is still char[2]. Similarly, in the third case, the sizeof(array) remains unchanged. Only in the forth case sizeof(typeof(array)) is converted to sizeof(char *) which gives the incorrect result. This is not limited to the operators-on-types, here is a case where it happens as a direct type in a declaration. Checking the translated code confirms that ptr is in fact a pointer to character type. int main(int argc, char * argv[]) { char array[2] = {5, 7}; typeof(array) ptr; ptr = &array[1]; } |