llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.43k stars 12.16k forks source link

non-type template-parameter of reference type confuses template specialization matching #40328

Open llvmbot opened 5 years ago

llvmbot commented 5 years ago
Bugzilla Link 40983
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor
CC @zygoloid

Extended Description

Consider the following MWE:

template<typename T, T v>
struct X {
};

template<bool &v>
struct X<bool &, v> {
};

As shown in https://www.godbolt.org/z/HqqLWu, the MWE is accepted by GCC when using C++14 (the compilation switches -std=c++14 -pedantic-errors) and when using C++17 (the compilation switches -std=c++17 -pedantic-errors).

Clang also accepts the MWE when using C++14 but not when using C++17.

A thread in the C++ std-discussion has just been started on this matter (see https://groups.google.com/a/isocpp.org/d/msg/std-discussion/etn0e3qhz28/Nmpmz7NwBAAJ), but no one has replied yet. Nevertheless, I think this is a bug considering that Clang accepts the MWE in C++14, and I think, there is no change in C++17 that justifies Clang behavior in rejecting the MWE in C++17.

This bug may also be related to this bug: llvm/llvm-project#38721

llvmbot commented 3 years ago

mentioned in issue llvm/llvm-bugzilla-archive#41829

llvmbot commented 5 years ago

I'm going to raise this with the C++ committee; I think this is a defect in P0127R2.

Has this issue been raised with the C++ committee?

Thank you.

ec04fc15-fa35-46f2-80e1-5d271f2ef708 commented 5 years ago

Bug llvm/llvm-bugzilla-archive#41829 has been marked as a duplicate of this bug.

ec04fc15-fa35-46f2-80e1-5d271f2ef708 commented 5 years ago

A thread in the C++ std-discussion has just been started

std-discussions is pretty broken right now; it randomly rejects a significant amount of mail as "spam" :(

The problem is that in C++17 onwards, the type of a non-type template parameter is deduced from the type of the argument. In C++14 and before, deducing the parameters of X from <bool&, v> deduces T=bool& from the first argument and v=v from the second. But in C++17 onwards, we also deduce T=bool from the second argument, which results in that no longer being a valid specialization, because we "don't know" what type T should be.

I'm going to raise this with the C++ committee; I think this is a defect in P0127R2.