On Thu, Jan 10, 2019 at 11:07:37AM +0100, Jakub Jelinek wrote: > 2019-01-10 Jakub Jelinek <ja...@redhat.com> > > PR c/88568 > * attribs.c (handle_dll_attribute): Clear TREE_STATIC after setting > DECL_EXTERNAL. > > * gcc.dg/pr88568.c: New test. > > --- gcc/attribs.c.jj 2019-01-05 12:06:12.055124090 +0100 > +++ gcc/attribs.c 2019-01-07 12:57:09.739782281 +0100 > @@ -1691,6 +1691,8 @@ handle_dll_attribute (tree * pnode, tree > a function global scope, unless declared static. */ > if (current_function_decl != NULL_TREE && !TREE_STATIC (node)) > TREE_PUBLIC (node) = 1; > + /* Clear TREE_STATIC because DECL_EXTERNAL is set. */ > + TREE_STATIC (node) = 0; > } > > if (*no_add_attrs == false)
The above change apparently broke handling of dllimport C++ static data members (on both trunk in 8.3), where the C++ FE requires that TREE_STATIC is set on the static data members, on the other side handles well the case when it is TREE_STATIC and DECL_EXTERNAL at the same time. So, the following patch partially reverts the above change, though for variables in RECORD/UNION_TYPE DECL_CONTEXTs only. That should keep the gcc.dg/pr88568.c testcase working, unbreaks the new testcase as well. Unfortunately, I have no way to test this on mingw or cygwin, on the other side it likely should work fine because for the static data members it will do what it used to do before the above patch and no issues were reported with those, except the pr88568.c C testcase. Ok for trunk (and after a while for 8.4 too)? 2019-03-05 Jakub Jelinek <ja...@redhat.com> PR c/88568 * attribs.c (handle_dll_attribute): Don't clear TREE_STATIC for dllimport on VAR_DECLs with RECORD_TYPE or UNION_TYPE DECL_CONTEXT. * g++.dg/other/pr88568.C: New test. --- gcc/attribs.c.jj 2019-01-10 11:44:07.122511397 +0100 +++ gcc/attribs.c 2019-03-05 13:59:51.745924578 +0100 @@ -1691,8 +1691,11 @@ handle_dll_attribute (tree * pnode, tree a function global scope, unless declared static. */ if (current_function_decl != NULL_TREE && !TREE_STATIC (node)) TREE_PUBLIC (node) = 1; - /* Clear TREE_STATIC because DECL_EXTERNAL is set. */ - TREE_STATIC (node) = 0; + /* Clear TREE_STATIC because DECL_EXTERNAL is set, unless + it is a C++ static data member. */ + if (DECL_CONTEXT (node) == NULL_TREE + || !RECORD_OR_UNION_TYPE_P (DECL_CONTEXT (node))) + TREE_STATIC (node) = 0; } if (*no_add_attrs == false) --- gcc/testsuite/g++.dg/other/pr88568.C.jj 2019-03-05 14:03:20.132509560 +0100 +++ gcc/testsuite/g++.dg/other/pr88568.C 2019-03-05 14:01:39.674155860 +0100 @@ -0,0 +1,13 @@ +// PR c/88568 +// { dg-do compile } +// { dg-require-dll "" } + +struct S { + __attribute__((dllimport)) static const char foo[]; +}; + +int +foo (int x) +{ + return S::foo[x]; +} Jakub