Skip to content

decltype of a class-type NTTP used as a requires-expression parameter #462

Description

@daveedvdv-nvidia

Issue Summary

For a class-type non-type template parameter F, decltype(F) (unparenthesized, note) should denote the declared type of the template parameter, and thus not be const-qualified (only the template parameter object that F names is const). So a requires-expression parameter declared as decltype(F) f should allow calling a non-const member function on f.

Instead, we treat f as const, and the requirement f() below is not satisfied. GCC 15.2, Clang 21.1 and MSVC accept the code.

Reproducing Source Code

struct NoConst {
  int operator()() { return 0; }
};
template<auto F>
inline constexpr bool const_callable_v = requires { F(); };
// decltype(F) is non-const NoConst
template<auto F>
inline constexpr bool non_const_callable_v =
    requires(decltype(F) f) { f(); };
static_assert(!const_callable_v<NoConst{}>);
static_assert(non_const_callable_v<NoConst{}>); // Incorrectly rejected.

Command-line Options

cpfe --c++20 repro.cpp

Type of Issue

[Front End] This code SHOULD compile with these options.

Additional Details

We diagnose this with:

"repro.cpp", line 14: error: static assertion failed
static_assert(non_const_callable_v<NoConst{}>); // Incorrectly rejected.
^

The same happens with --gnu_version=150200, --clang_version=210000, and --ms_c++20. The first static_assert (F itself is a const lvalue, so F() is ill-formed) is handled correctly.

This appears related to, but distinct from, #414 (fixed by #422): The failure persists with that fix.

Reproducing (Standard) Configuration(s)

linux-gcc-debug

Reproducing (Non-standard) Configuration

No response

I acknowledge that:

  • I have checked open issues and existing discussions before filing this report.
  • The reproducing source code that I have provided does not depend on headers that I have not included with my submission.
  • I have reduced the reproducing source code to the best of my ability.
  • I have selected at least one standard configuration or uploaded a non-standard configuration dump.
  • I understand code shared via this form is NOT confidential.
  • I have permission to share the reproducing source code and grant permission for the project to use the source code (or derivatives of the source code) to create tests.
  • I agree that any tests created using the reproducing source code (or deriatives of it) will be licensed under project license unless I included a LICENSE.txt file in my .zip or .tar.gz upload. If I included a LICENSE.txt file, any tests created using the reproducing source code will be governed by the terms of the license I provided instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions