llvm / llvm-project

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

Compiler confused when compiling template variable initialized by lambda-expression with default parameter. #33352

Open llvmbot opened 7 years ago

llvmbot commented 7 years ago
Bugzilla Link 34005
Version trunk
OS All
Reporter LLVM Bugzilla Contributor
CC @Quuxplusone

Extended Description

The code below fail to be compile.

// prog.cc

template struct X {}; template constexpr void f(X) {} template constexpr int v = [](int r = 0l) constexpr { return r; }();

int main() { f<v>(X<0>()); }

$ clang++ -std=c++1z prog.cc

prog.cc:6:5: error: no matching function for call to 'f' f<v>(X<0>()); ^~~~~ prog.cc:2:32: note: candidate function not viable: no known conversion from 'X<...>' to 'X<...>' for 1st argument template constexpr void f(X) {} ^ 1 error generated.

I think v is always 0, so f<v>(X<0>()) should match f<0>(X<0>);

And if lambda's default parameter type is int,

template constexpr int v = [](int r = 0) constexpr { return r; }();

There are no errors.

This link is the result executed by wandbox. https://wandbox.org/permlink/yjKqrYKQyl2YZ6PO

Quuxplusone commented 4 years ago

Confirmed and slightly simplified...

// https://godbolt.org/z/_g-9Bh template struct X {}; template constexpr void f(X) {}

template constexpr int v = [](int r=0L) { return r; }();

int main() { static constexpr int I = v; static_assert(I == 0); f<0>(X<0>()); f(X()); f<0>(X()); // clang error f<0>(X()); // clang error }

test.cc:16:5: error: no matching function for call to 'f' f<0>(X()); // clang error ^~~~ test.cc:6:32: note: candidate function template not viable: no known conversion from 'X<...>' to 'X<...>' for 1st argument template constexpr void f(X) {} ^ test.cc:17:5: error: no matching function for call to 'f' f<0>(X()); // clang error ^~~~ test.cc:6:32: note: candidate function template not viable: no known conversion from 'X<...>' to 'X<...>' for 1st argument template constexpr void f(X) {} ^