> From: Mark Mitchell [mailto:[EMAIL PROTECTED] > Sent: Thursday, September 14, 2006 3:38 PM > Danny Smith wrote: > > > The problem I had was with the second case below. We don't > know if a > > method is implicitly virtual until search.c:look_for_overrides_r). > > Would t be better to unset DECL_DLLIMPORT_P (and remove the > attribute > > as well) there? > > Ah, right, good point. I always forget that case,.partly because I > really think that processing should be done when the function is > declared. We can know whether it's virtual at that point, so > I think we > should. But, that's not how things work now. :-( > > So, perhaps the best place would be in check_for_override. That's > called for all methods when the class is complete. >
Revised patch. Tested on i686-pc-mingw32 Danny cp/ChangeLog PR target/27650 * class.c (check_for_override): Remove dllimport from virtual methods. testsuite/Changelog PR target/27650 * g++.dg/ext/dllimport12.C: New file. Index: cp/class.c =================================================================== *** cp/class.c (revision 117005) --- cp/class.c (working copy) *************** check_for_override (tree decl, tree ctyp *** 2342,2347 **** --- 2342,2357 ---- if (!DECL_VINDEX (decl)) DECL_VINDEX (decl) = error_mark_node; IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1; + if (DECL_DLLIMPORT_P (decl)) + { + /* When we handled the dllimport attribute we may not have known + that this function is virtual We can't use dllimport + semantics for a virtual method because we need to initialize + the vtable entry with a constant address. */ + DECL_DLLIMPORT_P (decl) = 0; + DECL_ATTRIBUTES (decl) + = remove_attribute ("dllimport", DECL_ATTRIBUTES (decl)); + } } } Index: testsuite/g++.dg/ext/dllimport12.C =================================================================== *** testsuite/g++.dg/ext/dllimport12.C (revision 0) --- testsuite/g++.dg/ext/dllimport12.C (revision 0) *************** *** 0 **** --- 1,22 ---- + // PR target/27650 + // Don't use dllimport semantics on virtual methods + // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} } + + // Don't import explicitly virtual method. + struct base + { + virtual void key_method(); + __attribute__((dllimport)) virtual ~base(); + }; + + void base::key_method() {} + + + // Nor an implicitly virtual method. + struct derived : public base + { + void key_method(); + __attribute__((dllimport)) ~derived(); + }; + + void derived::key_method() {}