Skip to content

[clang] C++20 Concept in Template Specialization Should Not See Protected Member. #115838

Open
@xkszltl

Description

@xkszltl

This bug exists in all released clang versions with C++20 support up to trunk.

The following code defined classes Publ/Priv/Prot with different visibility of member x, and inherit into a templated class D specialized by its accessibility using C++20 concept.
Boolean var has shows the specialization route.

In theory, only public member is visible, while protected/private are not.
These are checked by static_assert.

Clang mistakenly thinks protected member from class Prot is accessible, and failed to compile this code at the last static_assert, while any versions of gcc and msvc works.

Even more confusing, if we do the exact same thing again, with another class Same identical to Prot, but query the concept directly before template instantiation, clang will give opposite answer.

template<typename T> concept has_x = requires(T t){{ t.x };};

class Publ { public:    int x = 0; };
class Priv { private:   int x = 0; };
class Prot { protected: int x = 0; };
class Same { protected: int x = 0; };

template<typename T> class D;
template<typename T> requires ( has_x<T>) class D<T>: public T { public: static constexpr bool has = 1; };
template<typename T> requires (!has_x<T>) class D<T>: public T { public: static constexpr bool has = 0; };

// "Same" is identical to "Prot" but queried before used.
static_assert(!has_x<Same>,  "Protected should be invisible.");
static_assert(!D<Same>::has, "Protected should be invisible.");

static_assert( D<Publ>::has, "Public should be visible.");
static_assert(!D<Priv>::has, "Private should be invisible.");
static_assert(!D<Prot>::has, "Protected should be invisible.");  // clang failed here.

int main() { return 0; }

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"conceptsC++20 concepts

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions