Skip to content

rejects valid on if constexpr with dependent access restrictions #157281

@wheatman

Description

@wheatman

I think the following code is valid but being rejected

#include <type_traits>

class has_x {
    protected:
    int x();
};
class no_x {};

template <class A> class D : public A {
    public:
    int foo() {
        if constexpr (std::is_base_of_v<has_x,D>) {
            return has_x::x();
        }
        return 0;
    }
};

int y() {
    D<no_x> d;
    return d.foo();
}

The error is

<source>:15:27: error: 'x' is a protected member of 'has_x'
   15 |             return has_x::x();
      |                           ^
<source>:24:14: note: in instantiation of member function 'D<no_x>::foo' requested here
   24 |     return d.foo();
      |              ^
<source>:5:9: note: declared protected here
    5 |     int x();
      |         ^
1 error generated.
Compiler returned: 1

https://godbolt.org/z/G9v1qfWxj

I am not a standards expert, but we are inside a template entity so the statement should be discarded. I will note the switching which class is inside the template does allow the code to compile showing we are not ill-formed for every possible specialization.

The code is accepted by gcc 15.2 and msvc 19.43

Tested with clang 21.1 and and current master (4d0b816)

Metadata

Metadata

Assignees

No one assigned

    Labels

    c++clang:frontendLanguage frontend issues, e.g. anything involving "Sema"constexprAnything related to constant evaluationdiverges-from:edgDoes the clang frontend diverge from edg compiler on this issuediverges-from:gccDoes the clang frontend diverge from gcc on this issuediverges-from:msvcDoes the clang frontend diverge from msvc on this issuerejects-valid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions