Specification rule of "definition of a static data member is in the scope of its class" with a templated base class

GCC and Clang are both correct.

Particularly, from [temp.dep]/3 [emphasis mine]:

In the definition of a class or class template, the scope of a dependent base class is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member. [ Example:

typedef double A;
template<class T> class B {
  typedef int A;
};
template<class T> struct X : B<T> {
  A a;              // a has type double
};

The type name A in the definition of X<T> binds to the typedef name defined in the global namespace scope, not to the typedef name defined in the base class B<T>.  — end example ] [...]

In the definitions the static data members x1 and y1 of the of derived class template foobar:

template<int VALUE>
int foobar<VALUE>::x1 = foobar::foo();

template<int VALUE>
int foobar<VALUE>::y1 = foobar::z;

you are using the injected-class-name ([temp.local]/3) to access the dependent names ([temp.res]/9) foo and z from the base class template, whereas the unqualified names used in the definitions of the static data members x2 and y2 will not examine the scope of the dependent base class.


Note that we may bring in the names of the dependent base class into the scope of the derived class, redefining foobar as

template<int VALUE>
struct foobar: base<VALUE> {
    using base<VALUE>::foo;
    using base<VALUE>::z;
    static int x1;
    static int x2;
    static int y1;
    static int y2;
};

in which case the output of your program will be

10 10 -1 -1

This is just another case of the binding rules for non-depended names, which are looked up and bound at the point of template definition. (Not to be confused with ADL! Even while ADL would help with the call to foo() if it had any parameter.)
For the full details please read here: https://en.cppreference.com/w/cpp/language/dependent_name

Similar artifact happens with calling a function from template base class:

template <typename T>
struct A
{
    void f(){}
};

template <typename T>
struct B : A<T>
{
    void g()
    {
        A<T>::f();     // of course works
        this->f();     // this-> makes it depended, so it's bound only on instantiation time

        f();           // compilation error, no f() found

        using A<T>::f; // make the name available (and depended on the template)
        f();           // now it works
    }
};

https://gcc.godbolt.org/z/39KGvM