[llvm-bugs] [Bug 51472] New: Clang cannot resolve function template when an undefined template is used as a return type

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Aug 13 08:42:28 PDT 2021


            Bug ID: 51472
           Summary: Clang cannot resolve function template when an
                    undefined template is used as a return type
           Product: clang
           Version: unspecified
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: C++14
          Assignee: unassignedclangbugs at nondot.org
          Reporter: samolisov at gmail.com
                CC: blitzrakete at gmail.com, erik.pilkington at gmail.com,
                    llvm-bugs at lists.llvm.org, richard-llvm at metafoo.co.uk

Created attachment 25132
  --> https://bugs.llvm.org/attachment.cgi?id=25132&action=edit
Minimal example to reproduce

This bug affects building of MLIR at least on Windows using the clang-cl

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(


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

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210813/5dddf45d/attachment.html>

More information about the llvm-bugs mailing list