Summary: | [4.0 Regression] ICE: tree check: expected class 'declaration', have 'exceptional' (error_mark) in pushtag, at cp/name-lookup.c:4658 | ||
---|---|---|---|
Product: | gcc | Reporter: | David Fang <fang> |
Component: | c++ | Assignee: | Kriang Lerdsuwanakij <lerdsuwa> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | gcc-bugs, lerdsuwa |
Priority: | P2 | Keywords: | ice-on-valid-code, rejects-valid |
Version: | 4.0.0 | ||
Target Milestone: | 4.0.0 | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2005-03-13 14:25:34 | |
Bug Depends on: | |||
Bug Blocks: | 16995 |
Description
David Fang
2005-02-14 07:37:59 UTC
Confirmed, here is a testcase which is valid code (yes I checked to make sure that it is valid): namespace util { class persistent_object_manager; namespace memory { class pointer_manipulator { friend class persistent_object_manager; }; } } namespace util { using namespace memory; class persistent_object_manager { }; template <class T> class persistent_traits { friend class persistent_object_manager; }; } static util::persistent_traits<int> __blah__; : Search converges between 2004-11-25-014001-trunk (#656) and 2004-11-25-161001-trunk (#657). I think this is very related to PR 4403 (it might be fixed by that patch too). And related to PR 19403. 1) Has anyone figured out a workaround to this yet? I suppose I could remove some using namespace declarations and prefix type names with namespaces... I'll keep tinkering around. 2) New and perhaps closely related bug? g++-4.0 is also rejecting-valid the following code, tweaked from Andrew's example to reproduce something else I'm doing in my project: (using same version info as reported here) //-------------- snip --------------- namespace util { class persistent_object_manager; namespace memory { class pointer_manipulator { friend class persistent_object_manager; }; } } namespace util { using namespace memory; class persistent_object_manager { static const int foo; }; } namespace util { const int persistent_object_manager::foo = 666; } //--------------- end snip ---------------- g++-4.0 -c blah.cc -o blah.o reports: blah.cc:24: error: 'persistent_object_manager' has not been declared whereas 3.3 and 3.4 accept the code. Removing the friend declaration on line 8 allows g++-4.0 to compile. Removing the using namespace memory line 14 also allows g++-4.0 to compile. It was difficult to find a bug in the bugzilla database with the same characteristics. Should I file a separate bug report for this one or just tack it on to this one because it's probably closely related? -- David Workaround discovered (shortly after I asked for one, fancy that!) Declaring: using util::persistent_object_manager; inside the 'memory' namespace before the first friend declaration (after line 5) results in correct output for the examples listed above. The using declaration prevents (I think) injection of the friend class declaration into the 'memory' namespace and further confusion. Not a bad idea in practice, actually. Please, always fill a different bugreport for different testcases, unless you can prove it is exactly the same problem (and here you surely cannot). Then add references forth and back. If you want a work around, simply use this in the first 'friend' declaration: friend class util::persistent_object_manager; There is still uncertainty about whether name from 'using' declaration/directive is allowed (DR138) so your workaround may not work in the future. Look like caused by my changes to pushtag. Mainline is fixed. No error message is produced which is the correct behavior. Will recheck 4.0 branch. Cannot reproduce it now on 4.0. I think it's already fixed. ICE no longer reproducible. |