Opened 4 years ago
Last modified 4 years ago
#203 new defect
Polymorphic Structure Initalization Errors
Reported by: | ajbeach | Owned by: | |
---|---|---|---|
Priority: | major | Component: | cfa-cc |
Version: | 1.0 | Keywords: | |
Cc: |
Description (last modified by )
So I am pretty sure there is more than one bug here, but I'm not entirely sure where the lines are. There are a few places nothing is found, a few times extra options are found. There are times initialization style matters and there are times it doesn't.
Just because it might be a problem I made it a bit easier to pick out each one.
// Can be changed here or on the command line. #ifndef SHOW_ERROR #define SHOW_ERROR 0 #endif forall(dtype A) struct empty { // Nothing. }; forall(dtype B) struct counter { int count; }; forall(dtype C) struct wrap_e { empty(C) field; }; forall(dtype D) struct wrap_c { counter(D) field; }; forall(dtype E) struct wrap_d { E * field; }; forall(otype F) struct wrap_o { F field; }; forall(dtype G) struct base_vtable { base_vtable(G) const * const parent; }; forall(dtype H) struct child_vtable { base_vtable(H) const * const parent; }; empty(int) empty_obj = {}; empty(char) empty_obj = {}; counter(int) count_obj = {5}; counter(char) count_obj = {5}; base_vtable(int) base_vtable_instance @= { 0 }; base_vtable(char) base_vtable_instance @= { 0 }; #if SHOW_ERROR == 2 // No alternatives: wrap_e(char) error_obj @= { empty_obj }; #elif SHOW_ERROR == 3 // GCC: initializer element is not constant wrap_c(int) error_obj @= { count_obj }; #elif SHOW_ERROR == 4 // GCC: initializer element is not constant wrap_c(char) error_obj @= { count_obj }; #elif SHOW_ERROR == 7 // Initalizer too deep: wrap_e(bool) error_obj = { {} }; #elif SHOW_ERROR == 8 // Initalizer too deep: wrap_c(bool) error_obj = { { 0 } }; #elif SHOW_ERROR == 9 // Assertion failure: wrap_e(bool) error_obj @= { {} }; #endif // Related things that do not produce errors. int some_int = -7; char some_char = 'c'; wrap_e(int) wrap_obj = { empty_obj }; wrap_c(int) wrap_obj = { count_obj }; wrap_d(int) wrap_obj = { &some_int }; wrap_d(char) wrap_obj @= { &some_char }; wrap_o(int) wrap_obj = { 13 }; wrap_o(char) wrap_obj @= { 'c' }; // related to SHOW_ERROR == 3 void local_case3() { // correctly picks preferred among 2 alternatives wrap_c(int) error_obj @= { count_obj }; } // related to SHOW_ERROR == 4 void local_case4() { // correctly picks preferred among 2 alternatives wrap_c(char) error_obj @= { count_obj }; } // formerely SHOW_ERROR == 5 // correctly picks preferred among 2 alternatives child_vtable(int) child_vtable_instance = { &base_vtable_instance }; // formerely SHOW_ERROR == 6 // correctly picks preferred among 2 alternatives child_vtable(char) child_vtable_instance @= { &base_vtable_instance }; int main(void) { wrap_e(int) wrap_obj = { empty_obj }; wrap_c(int) wrap_obj = { count_obj }; wrap_d(int) wrap_obj = { &some_int }; wrap_d(char) wrap_obj @= { &some_char }; wrap_o(int) wrap_obj = { 13 }; wrap_o(char) wrap_obj @= { 'c' }; { wrap_e(bool) alpha; wrap_e(bool) beta; beta = alpha; // alpha.field = beta.field; (See #166.) wrap_e(bool) delta = { beta }; } { wrap_c(bool) alpha; wrap_c(bool) beta; beta = alpha; // alpha.field = beta.field; (See #166.) wrap_c(bool) delta = { beta }; } return 0; }
Change History (6)
comment:1 Changed 4 years ago by
Description: | modified (diff) |
---|
comment:2 Changed 4 years ago by
Description: | modified (diff) |
---|---|
Summary: | Polymorphic Structure and Polymorphic Structure Errors → Polymorphic Structure Initalization Errors |
comment:3 Changed 4 years ago by
Description: | modified (diff) |
---|
One of the cases actually did work, removed the old first case.
comment:4 Changed 4 years ago by
So #189 has been solved and that fixed 3-6, it might be time to pull out the remaining cases into new more descriptive tickets and close this one.
comment:5 Changed 4 years ago by
bug #2 is caused by this line of code in AggregateIterator::operator*:
// CurrentObject.cc:298 virtual std::list<InitAlternative> operator*() const { if (memberIter && *memberIter) { // if empty object, *memberIter is invalid std::list<InitAlternative> ret = memberIter->first(); PRINT( std::cerr << "sub: " << sub << std::endl; ) for ( InitAlternative & alt : ret ) { PRINT( std::cerr << "iterating and adding designators" << std::endl; ) alt.designation->get_designators().push_front( new VariableExpr( strict_dynamic_cast< ObjectDecl * >( *curMember ) ) ); // need to substitute for generic types, so that casts are to concrete types PRINT( std::cerr << " type is: " << alt.type; ) sub.apply( alt.type ); // also apply to designation?? PRINT( std::cerr << " ==> " << alt.type << std::endl; ) } return ret; } return std::list<InitAlternative>(); // <- here }
this causes an empty object to have no init alternatives in a non-constructed initializer expression (@= statement)
intuitively, this corner case should produce an "empty alternative" rather than no alternative. I'm not clear about how the alternatives are described, so I don't know what is the correct fix.
comment:6 Changed 4 years ago by
Description: | modified (diff) |
---|
Modified the test program for accuracy with our compiler's current behaviour. Resolver behaviour that now works (since fix of #189) moved to section "Related things that do not produce errors," which removes error cases 4 and 5 and splits cases 3 and 4. Additionally, in cases 3 and 4, having the declaration in a function works (so that's now under "Related things that do not produce errors") while having the declaration be global does not work (so that's now shown with the now-reachable GCC error).
Some of the error cases may have actually been bad code. I removed them and renamed the ticket to hopefully describe the remaining cases better. I also included some more examples of code that do work because I dug up a few cases (copy constructor) that does work. Also I dug up a few more cases that are errors but are almost certainly other errors, maybe this ticket should be split up.