https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69020

            Bug ID: 69020
           Summary: wrong ADL for attribute cleanup functions
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

While working an a fix for bug 58109 I noticed that the comment in
is_late_template_attribute() suggests that attribute cleanup may not be handled
as one would expect for type-dependent functions:

      /* If the first attribute argument is an identifier, only consider
         second and following arguments.  Attributes like mode, format,
         cleanup and several target specific attributes aren't late
         just because they have an IDENTIFIER_NODE as first argument.  */

The test case below shows that the cleanup attribute ends up resolving the
type-dependent reference to foo to the synonymous member of the dependent class
as opposed to the one at namespace scope as a call to foo does.  All versions
of GCC as far back as 4.5 have this bug.

$ cat b.cpp && /build/gcc-trunk-svn/gcc/xg++ -B /build/gcc-trunk-svn/gcc -Wall
-Wextra -Wpedantic -L
/build/gcc-trunk-svn/x86_64-pc-linux-gnu/libstdc++-v3/src/.libs b.cpp &&
./a.out
extern "C" int printf (const char*, ...);

template <class T> struct A {
    static void foo (T*) { printf ("%s\n", __PRETTY_FUNCTION__); }
};

void foo (int*) { printf ("%s\n", __PRETTY_FUNCTION__); }

template <class T> struct B: A<T> {
    void bar () {
        T a __attribute__ ((cleanup (foo)));   // should invoke ::foo(int*)
        printf ("%s calling ", __PRETTY_FUNCTION__);
        foo (&a);
        printf ("cleanup calling ");
    }
};

int main ()
{
    B<int>().bar ();
}
void B<T>::bar() [with T = int] calling void foo(int*)
cleanup calling static void A<T>::foo(T*) [with T = int]

Reply via email to