<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - Clang cannot resolve function template when an undefined template is used as a return type"
href="https://bugs.llvm.org/show_bug.cgi?id=51472">51472</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Clang cannot resolve function template when an undefined template is used as a return type
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Windows NT
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>C++14
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>samolisov@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=25132" name="attach_25132" title="Minimal example to reproduce">attachment 25132</a> <a href="attachment.cgi?id=25132&action=edit" title="Minimal example to reproduce">[details]</a></span>
Minimal example to reproduce
This bug affects building of MLIR at least on Windows using the clang-cl
frontend.
Please see an attached file or the following header in the MLIR sources:
mlir\include\mlir\TableGen\Format.h. There are two function templates with the
same name:
inline auto tgfmt(StringRef fmt, const FmtContext *ctx, Ts &&...vals)
-> FmtObject<decltype(std::make_tuple(
llvm::detail::build_format_adapter(std::forward<Ts>(vals))...))>
and
inline FmtStrVecObject tgfmt(StringRef fmt, const FmtContext *ctx,
ArrayRef<std::string> params)
The functions are called from the mlir\tools\mlir-tblgen\PassGen.cpp file (see
lines 283 and 948, the last one is the code std::string symbol = tgarfmt(fmt,
&fmtCtx.addSubst("_loc", locToUse), attrs); in the
PatternEmitter::handleReplaceWithNativeCodeCall function).
The most interesting part of the first function's return type is the wrapped in
a tuple result of the llvm::detail::build_format_adapter function. There are
numerous overloading for llvm::detail::build_format_adapter function with
condition compilation based on std::enable_if_t, the most interesting for us is
the following:
template <typename T>
std::enable_if_t<uses_missing_provider<T>::value, missing_format_adapter<T>>
build_format_adapter(T &&) {
return missing_format_adapter<T>();
}
What is the missing_format_adapter? This is just an undefined template:
template <typename T> class missing_format_adapter;
The problem is the following: even if our Ts in the first function we started
from, tgfmt, is a container type convertible to ArrayRef<std::string>
(ArrayRef<std::string> has an implicit constructor from an instance of that
type) e.g. SmallVector<std::string> or std::vector<std::string> but the type
has no defined `<<` operator or format_adapter, so the type that makes a
resolution to the undefined template missing_format_adapter, clang throws the
compilation error and **won't choose the second overload of the tgfmt function
with ArrayRef<std::sting> as the third argument**:
tgfmt(StringRef fmt, const FmtContext *ctx, ArrayRef<std::string> params)
MSVC, for example, chooses this function in the same situation. I tried the
current main of clang as well as clang 12 (built from sources as well as an
official release for Windows) but have got the same error during MLIR
compilation.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>