<div dir="ltr">Hans, can we get this onto the Clang 4 release branch (along with the documentation added in r<span style="font-size:12.8px">292558 and fixed in r</span><span style="font-size:12.8px">292559)</span>? This will allow us to avoid libc++ carrying a version test for Clang, and allow it to cleanly finish off its implementation of <span style="font-size:12.8px">P0426.</span></div><div class="gmail_extra"><br><div class="gmail_quote">On 19 January 2017 at 16:45, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Thu Jan 19 18:45:35 2017<br>
New Revision: 292555<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=292555&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=292555&view=rev</a><br>
Log:<br>
P0426: Make the library implementation of constexpr char_traits a little easier<br>
by providing a memchr builtin that returns char* instead of void*.<br>
<br>
Also add a __has_feature flag to indicate the presence of constexpr forms of<br>
the relevant <string> functions.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/<wbr>Builtins.def<br>
    cfe/trunk/lib/AST/<wbr>ExprConstant.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>CGBuiltin.cpp<br>
    cfe/trunk/lib/Lex/<wbr>PPMacroExpansion.cpp<br>
    cfe/trunk/test/CodeGenCXX/<wbr>builtins.cpp<br>
    cfe/trunk/test/Lexer/has_<wbr>feature_cxx0x.cpp<br>
    cfe/trunk/test/SemaCXX/<wbr>constexpr-string.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>Builtins.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=292555&r1=292554&r2=292555&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/Builtins.def?rev=<wbr>292555&r1=292554&r2=292555&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>Builtins.def (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>Builtins.def Thu Jan 19 18:45:35 2017<br>
@@ -1339,6 +1339,7 @@ BUILTIN(__builtin_smulll_<wbr>overflow, "bSLL<br>
 BUILTIN(__builtin_addressof, "v*v&", "nct")<br>
 BUILTIN(__builtin_operator_<wbr>new, "v*z", "c")<br>
 BUILTIN(__builtin_operator_<wbr>delete, "vv*", "n")<br>
+BUILTIN(__builtin_char_<wbr>memchr, "c*cC*iz", "n")<br>
<br>
 // Safestack builtins<br>
 BUILTIN(__builtin___get_<wbr>unsafe_stack_start, "v*", "Fn")<br>
<br>
Modified: cfe/trunk/lib/AST/<wbr>ExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=292555&r1=292554&r2=292555&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>ExprConstant.cpp?rev=292555&<wbr>r1=292554&r2=292555&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/<wbr>ExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/AST/<wbr>ExprConstant.cpp Thu Jan 19 18:45:35 2017<br>
@@ -5683,6 +5683,7 @@ bool PointerExprEvaluator::<wbr>VisitBuiltinC<br>
   case Builtin::BI__builtin_strchr:<br>
   case Builtin::BI__builtin_wcschr:<br>
   case Builtin::BI__builtin_memchr:<br>
+  case Builtin::BI__builtin_char_<wbr>memchr:<br>
   case Builtin::BI__builtin_wmemchr: {<br>
     if (!Visit(E->getArg(0)))<br>
       return false;<br>
@@ -5720,6 +5721,7 @@ bool PointerExprEvaluator::<wbr>VisitBuiltinC<br>
       // Fall through.<br>
     case Builtin::BImemchr:<br>
     case Builtin::BI__builtin_memchr:<br>
+    case Builtin::BI__builtin_char_<wbr>memchr:<br>
       // memchr compares by converting both sides to unsigned char. That's also<br>
       // correct for strchr if we get this far (to cope with plain char being<br>
       // unsigned in the strchr case).<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>CGBuiltin.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=292555&r1=292554&r2=292555&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CGBuiltin.cpp?rev=292555&r1=<wbr>292554&r2=292555&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>CGBuiltin.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>CGBuiltin.cpp Thu Jan 19 18:45:35 2017<br>
@@ -1189,6 +1189,10 @@ RValue CodeGenFunction::<wbr>EmitBuiltinExpr(<br>
     return RValue::get(Dest.getPointer())<wbr>;<br>
   }<br>
<br>
+  case Builtin::BI__builtin_char_<wbr>memchr:<br>
+    BuiltinID = Builtin::BI__builtin_memchr;<br>
+    break;<br>
+<br>
   case Builtin::BI__builtin___memcpy_<wbr>chk: {<br>
     // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.<br>
     llvm::APSInt Size, DstSize;<br>
<br>
Modified: cfe/trunk/lib/Lex/<wbr>PPMacroExpansion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=292555&r1=292554&r2=292555&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Lex/<wbr>PPMacroExpansion.cpp?rev=<wbr>292555&r1=292554&r2=292555&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Lex/<wbr>PPMacroExpansion.cpp (original)<br>
+++ cfe/trunk/lib/Lex/<wbr>PPMacroExpansion.cpp Thu Jan 19 18:45:35 2017<br>
@@ -1183,6 +1183,7 @@ static bool HasFeature(const Preprocesso<br>
       .Case("cxx_attributes", LangOpts.CPlusPlus11)<br>
       .Case("cxx_auto_type", LangOpts.CPlusPlus11)<br>
       .Case("cxx_constexpr", LangOpts.CPlusPlus11)<br>
+      .Case("cxx_constexpr_string_<wbr>builtins", LangOpts.CPlusPlus11)<br>
       .Case("cxx_decltype", LangOpts.CPlusPlus11)<br>
       .Case("cxx_decltype_<wbr>incomplete_return_types", LangOpts.CPlusPlus11)<br>
       .Case("cxx_default_function_<wbr>template_args", LangOpts.CPlusPlus11)<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/<wbr>builtins.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/builtins.cpp?rev=292555&r1=292554&r2=292555&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>CodeGenCXX/builtins.cpp?rev=<wbr>292555&r1=292554&r2=292555&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/<wbr>builtins.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/<wbr>builtins.cpp Thu Jan 19 18:45:35 2017<br>
@@ -26,3 +26,7 @@ int x = __builtin_abs(-2);<br>
 long y = __builtin_abs(-2l);<br>
 // CHECK:  [[Y:%.+]] = call i64 @_Z13__builtin_absl(i64 -2)<br>
 // CHECK:  store i64 [[Y]], i64* @y, align 8<br>
+<br>
+extern const char char_memchr_arg[32];<br>
+char *memchr_result = __builtin_char_memchr(char_<wbr>memchr_arg, 123, 32);<br>
+// CHECK: call i8* @memchr(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @char_memchr_arg, i32 0, i32 0), i32 123, i64 32)<br>
<br>
Modified: cfe/trunk/test/Lexer/has_<wbr>feature_cxx0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/has_feature_cxx0x.cpp?rev=292555&r1=292554&r2=292555&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Lexer/<wbr>has_feature_cxx0x.cpp?rev=<wbr>292555&r1=292554&r2=292555&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Lexer/has_<wbr>feature_cxx0x.cpp (original)<br>
+++ cfe/trunk/test/Lexer/has_<wbr>feature_cxx0x.cpp Thu Jan 19 18:45:35 2017<br>
@@ -301,6 +301,17 @@ int no_constexpr();<br>
 // CHECK-11: has_constexpr<br>
 // CHECK-NO-11: no_constexpr<br>
<br>
+#if __has_feature(cxx_constexpr_<wbr>string_builtins)<br>
+int has_constexpr_string_builtins(<wbr>);<br>
+#else<br>
+int no_constexpr_string_builtins()<wbr>;<br>
+#endif<br>
+<br>
+// CHECK-1Z: has_constexpr_string_builtins<br>
+// CHECK-14: has_constexpr_string_builtins<br>
+// CHECK-11: has_constexpr_string_builtins<br>
+// CHECK-NO-11: no_constexpr_string_builtins<br>
+<br>
 #if __has_feature(cxx_generalized_<wbr>initializers)<br>
 int has_generalized_initializers()<wbr>;<br>
 #else<br>
<br>
Modified: cfe/trunk/test/SemaCXX/<wbr>constexpr-string.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-string.cpp?rev=292555&r1=292554&r2=292555&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaCXX/constexpr-string.cpp?<wbr>rev=292555&r1=292554&r2=<wbr>292555&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/<wbr>constexpr-string.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/<wbr>constexpr-string.cpp Thu Jan 19 18:45:35 2017<br>
@@ -166,6 +166,27 @@ namespace StrchrEtc {<br>
   static_assert(__builtin_<wbr>memchr(nullptr, 'x', 3) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}<br>
   static_assert(__builtin_<wbr>memchr(nullptr, 'x', 0) == nullptr); // FIXME: Should we reject this?<br>
<br>
+  static_assert(__builtin_char_<wbr>memchr(kStr, 'a', 0) == nullptr);<br>
+  static_assert(__builtin_char_<wbr>memchr(kStr, 'a', 1) == kStr);<br>
+  static_assert(__builtin_char_<wbr>memchr(kStr, '\0', 5) == nullptr);<br>
+  static_assert(__builtin_char_<wbr>memchr(kStr, '\0', 6) == kStr + 5);<br>
+  static_assert(__builtin_char_<wbr>memchr(kStr, '\xff', 8) == kStr + 4);<br>
+  static_assert(__builtin_char_<wbr>memchr(kStr, '\xff' + 256, 8) == kStr + 4);<br>
+  static_assert(__builtin_char_<wbr>memchr(kStr, '\xff' - 256, 8) == kStr + 4);<br>
+  static_assert(__builtin_char_<wbr>memchr(kFoo, 'x', 3) == nullptr);<br>
+  static_assert(__builtin_char_<wbr>memchr(kFoo, 'x', 4) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}<br>
+  static_assert(__builtin_char_<wbr>memchr(nullptr, 'x', 3) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}}<br>
+  static_assert(__builtin_char_<wbr>memchr(nullptr, 'x', 0) == nullptr); // FIXME: Should we reject this?<br>
+<br>
+  static_assert(*__builtin_char_<wbr>memchr(kStr, '\xff', 8) == '\xff');<br>
+  constexpr bool char_memchr_mutable() {<br>
+    char buffer[] = "mutable";<br>
+    *__builtin_char_memchr(buffer, 't', 8) = 'r';<br>
+    *__builtin_char_memchr(buffer, 'm', 8) = 'd';<br>
+    return __builtin_strcmp(buffer, "durable") == 0;<br>
+  }<br>
+  static_assert(char_memchr_<wbr>mutable());<br>
+<br>
   constexpr bool a = !strchr("hello", 'h'); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strchr' cannot be used in a constant expression}}<br>
   constexpr bool b = !memchr("hello", 'h', 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'memchr' cannot be used in a constant expression}}<br>
 }<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>