[LLVMbugs] [Bug 14550] New: explicit specialization omits functions that call constexpr strlen

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sat Dec 8 15:42:04 PST 2012


http://llvm.org/bugs/show_bug.cgi?id=14550

             Bug #: 14550
           Summary: explicit specialization omits functions that call
                    constexpr strlen
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++11
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: jyasskin at google.com
                CC: dgregor at apple.com, llvmbugs at cs.uiuc.edu
    Classification: Unclassified


Apply the following patch to libc++, and run buildit (instructions at
http://libcxx.llvm.org/) with clang r163674:

diff --git a/include/string b/include/string
index 5bf42f0..6e2f890 100644
--- a/include/string
+++ b/include/string
@@ -642,7 +642,7 @@ struct _LIBCPP_VISIBLE char_traits<char>
     static int compare(const char_type* __s1, const char_type* __s2, size_t
__n)
         {return memcmp(__s1, __s2, __n);}
     _LIBCPP_INLINE_VISIBILITY
-    static size_t length(const char_type* __s) {return strlen(__s);}
+    static constexpr size_t length(const char_type* __s) {return strlen(__s);}
     _LIBCPP_INLINE_VISIBILITY
     static const char_type* find(const char_type* __s, size_t __n, const
char_type& __a)
         {return (const char_type*)memchr(__s, to_int_type(__a), __n);}


I get the following, with some of the "referenced from" omitted:

Undefined symbols for architecture i386:
  "std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::compare(char const*) const", referenced from:
      std::__1::locale::global(std::__1::locale const&) in locale.o
      std::__1::locale::operator==(std::__1::locale const&) const in locale.o
  "std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::append(char const*)", referenced from:
      std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::operator+=(char const*) in string.o
      std::__1::system_error::__init(std::__1::error_code const&,
std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >) in system_error.o
     (maybe you meant: std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*,
unsigned long))
  "std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::assign(char const*)", referenced from:
      std::__1::moneypunct_byname<char, false>::init(char const*) in locale.o
      std::__1::moneypunct_byname<char, true>::init(char const*) in locale.o
      std::__1::moneypunct_byname<wchar_t, false>::init(char const*) in
locale.o
      std::__1::moneypunct_byname<wchar_t, true>::init(char const*) in locale.o
      std::__1::numpunct_byname<char>::__init(char const*) in locale.o
      std::__1::numpunct_byname<wchar_t>::__init(char const*) in locale.o
      std::__1::__time_get_c_storage<char>::__weeks() const in locale.o
      ...
     (maybe you meant: std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >::assign(char const*,
unsigned long))
  "std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::insert(unsigned long, char const*)", referenced
from:
      ...
     (maybe you meant: std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >::insert(unsigned long,
char const*, unsigned long))
  "std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::replace(unsigned long, unsigned long, char
const*)", referenced from:
      std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::replace(std::__1::__wrap_iter<char const*>,
std::__1::__wrap_iter<char const*>, char const*) in string.o
     (maybe you meant: std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >::replace(unsigned
long, unsigned long, char const*, unsigned long))
  "std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> >::basic_string(char const*)", referenced from:
      ...
     (maybe you meant: std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(char
const*, unsigned long), std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(char
const*, unsigned long, std::__1::allocator<char> const&) )
  "std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> > std::__1::operator+<char,
std::__1::char_traits<char>, std::__1::allocator<char> >(char const*,
std::__1::basic_string<char, std::__1::char_traits<char>,
std::__1::allocator<char> > const&)", referenced from:
      ...
ld: symbol(short) not found for architecture i386

-------------

basic_string<char> is declared as an extern template in include/string and
explicitly specialized in src/string.cpp. The missing functions all call the
traits::length() static method that I made constexpr. It calls strlen, which
isn't itself constexpr but is recognized as a constexpr builtin by clang.

Replacing the strlen(__s) call with "3" fixes the link error. Using
__builtin_strlen doesn't help.

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list