<div dir="ltr">Can we revert until a fix is ready? 7 days with msan failures is too many.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Jan 23, 2014 at 8:08 PM, Richard Smith <span dir="ltr"><<a href="mailto:metafoo@gmail.com" target="_blank">metafoo@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Looks like the msan build bot has found a bug here:<br><br><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/1844/steps/annotate/logs/stdio" target="_blank">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/1844/steps/annotate/logs/stdio</a><br>

<div><br></div><div>It appears that some path through the code doesn't initialize <span style="line-height:19px">Deprecated</span><span style="line-height:19px">String</span><u></u><span style="line-height:19px">Literal</span><span style="line-height:19px">ToCharP</span><u style="line-height:19px"></u><span style="line-height:19px">tr.</span></div>
<div class="HOEnZb"><div class="h5">
<br><div>On Fri Jan 17 2014 at 1:15:20 PM, Ismail Pazarbasi <<a href="mailto:ismail.pazarbasi@gmail.com" target="_blank">ismail.pazarbasi@gmail.com</a>> wrote:</div><blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Author: ismailp<br>
Date: Fri Jan 17 15:08:52 2014<br>
New Revision: 199513<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=199513&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>pr<u></u>oject?rev=199513&view=rev</a><br>
Log:<br>
Fix string-literal to char* conversion in overload resolution for C++11<br>
<br>
String literal to char* conversion is deprecated in C++03, and is removed in<br>
C++11. We still accept this conversion in C++11 mode as an extension, if we find<br>
it in the best viable function.<br>
<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/<u></u><u></u>DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/Sema/<u></u>SemaExprCXX<u></u>.cpp<br>
    cfe/trunk/lib/Sema/<u></u>SemaOverloa<u></u>d.cpp<br>
    cfe/trunk/test/SemaCXX/cxx0x-<u></u>t<u></u>ype-convert-construct.cpp<br>
    cfe/trunk/test/SemaCXX/<u></u>depreca<u></u>ted.cpp<br>
    cfe/trunk/test/SemaCXX/<u></u>overloa<u></u>d-0x.cpp<br>
    cfe/trunk/unittests/<u></u>ASTMatcher<u></u>s/ASTMatchersTest.<u></u>cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<u></u><u></u>DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=199513&r1=199512&r2=199513&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>pr<u></u>oject/cfe/trunk/include/<u></u>clang/<u></u>Basic/<u></u>DiagnosticSemaKinds.td?<u></u>rev=<u></u>199513&r1=199512&r2=<u></u>199513&<u></u>view=diff</a><br>


==============================<u></u><u></u>==============================<u></u><u></u>==================<br>
--- cfe/trunk/include/clang/Basic/<u></u><u></u>DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<u></u><u></u>DiagnosticSemaKinds.td Fri Jan 17 15:08:52 2014<br>
@@ -4534,6 +4534,9 @@ def ext_array_init_parens : ExtWarn<<br>
 def warn_deprecated_string_<u></u>literal<u></u>_conversion : Warning<<br>
   "conversion from string literal to %0 is deprecated">,<br>
   InGroup<<u></u>CXX11CompatDeprecated<u></u>WritableS<u></u>tr>;<br>
+def ext_deprecated_string_literal_<u></u><u></u>conversion : ExtWarn<<br>
+  "ISO C++11 does not allow conversion from string literal to %0">,<br>
+  InGroup<<u></u>CXX11CompatDeprecated<u></u>WritableS<u></u>tr>, SFINAEFailure;<br>
 def warn_deprecated_string_<u></u>literal<u></u>_conversion_c : Warning<<br>
   "dummy warning to enable -fconst-strings">, InGroup<DeprecatedWritableStr><u></u><u></u>, DefaultIgnore;<br>
 def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;<br>
<br>
Modified: cfe/trunk/lib/Sema/<u></u>SemaExprCXX<u></u>.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=199513&r1=199512&r2=199513&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>pr<u></u>oject/cfe/trunk/lib/Sema/<u></u>SemaE<u></u>xprCXX.cpp?rev=199513&r1=<u></u>19951<u></u>2&r2=199513&view=diff</a><br>


==============================<u></u><u></u>==============================<u></u><u></u>==================<br>
--- cfe/trunk/lib/Sema/<u></u>SemaExprCXX<u></u>.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<u></u>SemaExprCXX<u></u>.cpp Fri Jan 17 15:08:52 2014<br>
@@ -3058,9 +3058,12 @@ Sema::<u></u>PerformImplicitConversio<u></u>n(Expr *Fr<br>
                              CK_NoOp, VK, /*BasePath=*/0, CCK).take();<br>
<br>
     if (SCS.<u></u>DeprecatedStringLiteralTo<u></u>CharP<u></u>tr &&<br>
-        !getLangOpts().<u></u>WritableString<u></u>s)<br>
-      Diag(From->getLocStart(), diag::warn_deprecated_string_<u></u>l<u></u>iteral_conversion)<br>
+        !getLangOpts().<u></u>WritableString<u></u>s) {<br>
+      Diag(From->getLocStart(), getLangOpts().CPlusPlus11<br>
+           ? diag::ext_deprecated_string_<u></u>li<u></u>teral_conversion<br>
+           : diag::warn_deprecated_string_<u></u>l<u></u>iteral_conversion)<br>
         << ToType.getNonReferenceType();<br>
+    }<br>
<br>
     break;<br>
   }<br>
<br>
Modified: cfe/trunk/lib/Sema/<u></u>SemaOverloa<u></u>d.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=199513&r1=199512&r2=199513&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>pr<u></u>oject/cfe/trunk/lib/Sema/<u></u>SemaO<u></u>verload.cpp?rev=199513&<u></u>r1=<u></u>199512&r2=199513&view=diff</a><br>


==============================<u></u><u></u>==============================<u></u><u></u>==================<br>
--- cfe/trunk/lib/Sema/<u></u>SemaOverloa<u></u>d.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<u></u>SemaOverloa<u></u>d.cpp Fri Jan 17 15:08:52 2014<br>
@@ -1443,7 +1443,6 @@ static bool IsStandardConversion(Sema &S<br>
<br>
   // Standard conversions (C++ [conv])<br>
   SCS.setAsIdentityConversion()<u></u>;<br>
-  SCS.<u></u>DeprecatedStringLiteralTo<u></u>CharP<u></u>tr = false;<br>
   SCS.IncompatibleObjC = false;<br>
   SCS.setFromType(FromType);<br>
   SCS.CopyConstructor = 0;<br>
@@ -1542,7 +1541,7 @@ static bool IsStandardConversion(Sema &S<br>
     FromType = S.Context.getArrayDecayedType(<u></u><u></u>FromType);<br>
<br>
     if (S.<u></u>IsStringLiteralToNonConstPo<u></u>int<u></u>erConversion(From, ToType)) {<br>
-      // This conversion is deprecated. (C++ D.4).<br>
+      // This conversion is deprecated in C++03 (D.4)<br>
       SCS.<u></u>DeprecatedStringLiteralTo<u></u>CharP<u></u>tr = true;<br>
<br>
       // For the purpose of ranking in overload resolution<br>
@@ -3259,18 +3258,15 @@ Sema::<u></u>DiagnoseMultipleUserDefi<u></u>nedCon<u></u>vers<br>
     IsUserDefinedConversion(*<u></u>this, From, ToType, ICS.UserDefined,<br>
                             CandidateSet, false, false);<br>
   if (OvResult == OR_Ambiguous)<br>
-    Diag(From->getLocStart(),<br>
-         diag::err_typecheck_ambiguous_<u></u><u></u>condition)<br>
-          << From->getType() << ToType << From->getSourceRange();<br>
+    Diag(From->getLocStart(), diag::err_typecheck_ambiguous_<u></u><u></u>condition)<br>
+        << From->getType() << ToType << From->getSourceRange();<br>
   else if (OvResult == OR_No_Viable_Function && !CandidateSet.empty()) {<br>
     if (!RequireCompleteType(From-><u></u>ge<u></u>tLocStart(), ToType,<br>
-                          diag::err_typecheck_<u></u>nonviable_<u></u>condition_<u></u>incomplete,<br>
+                             diag::err_typecheck_nonviable_<u></u><u></u>condition_incomplete,<br>
                              From->getType(), From->getSourceRange()))<br>
-      Diag(From->getLocStart(),<br>
-           diag::err_typecheck_nonviable_<u></u><u></u>condition)<br>
-           << From->getType() << From->getSourceRange() << ToType;<br>
-  }<br>
-  else<br>
+      Diag(From->getLocStart(), diag::err_typecheck_nonviable_<u></u><u></u>condition)<br>
+          << From->getType() << From->getSourceRange() << ToType;<br>
+  } else<br>
     return false;<br>
   CandidateSet.NoteCandidates(*<u></u><u></u>this, OCD_AllCandidates, From);<br>
   return true;<br>
@@ -3280,37 +3276,43 @@ Sema::<u></u>DiagnoseMultipleUserDefi<u></u>nedCon<u></u>vers<br>
 /// of two user-defined conversion sequences to determine whether any ordering<br>
 /// is possible.<br>
 static ImplicitConversionSequence::<u></u>Co<u></u>mpareKind<br>
-compareConversionFunctions(<u></u>Se<u></u>ma &S,<br>
-                           FunctionDecl *Function1,<br>
+compareConversionFunctions(<u></u>Se<u></u>ma &S, FunctionDecl *Function1,<br>
                            FunctionDecl *Function2) {<br>
   if (!S.getLangOpts().ObjC1 || !S.getLangOpts().CPlusPlus11)<br>
     return ImplicitConversionSequence::<u></u>In<u></u>distinguishable;<br>
-<br>
+<br>
   // Objective-C++:<br>
   //   If both conversion functions are implicitly-declared conversions from<br>
-  //   a lambda closure type to a function pointer and a block pointer,<br>
+  //   a lambda closure type to a function pointer and a block pointer,<br>
   //   respectively, always prefer the conversion to a function pointer,<br>
   //   because the function pointer is more lightweight and is more likely<br>
   //   to keep code working.<br>
   CXXConversionDecl *Conv1 = dyn_cast<CXXConversionDecl>(<u></u>Fu<u></u>nction1);<br>
   if (!Conv1)<br>
     return ImplicitConversionSequence::<u></u>In<u></u>distinguishable;<br>
-<br>
+<br>
   CXXConversionDecl *Conv2 = dyn_cast<CXXConversionDecl>(<u></u>Fu<u></u>nction2);<br>
   if (!Conv2)<br>
     return ImplicitConversionSequence::<u></u>In<u></u>distinguishable;<br>
-<br>
+<br>
   if (Conv1->getParent()->isLambda(<u></u><u></u>) && Conv2->getParent()->isLambda()<u></u><u></u>) {<br>
     bool Block1 = Conv1->getConversionType()-><u></u>is<u></u>BlockPointerType();<br>
     bool Block2 = Conv2->getConversionType()-><u></u>is<u></u>BlockPointerType();<br>
     if (Block1 != Block2)<br>
-      return Block1? ImplicitConversionSequence::<u></u>Wo<u></u>rse<br>
-                   : ImplicitConversionSequence::<u></u>Be<u></u>tter;<br>
+      return Block1 ? ImplicitConversionSequence::<u></u>Wo<u></u>rse<br>
+                    : ImplicitConversionSequence::<u></u>Be<u></u>tter;<br>
   }<br>
<br>
   return ImplicitConversionSequence::<u></u>In<u></u>distinguishable;<br>
 }<br>
-<br>
+<br>
+static bool hasDeprecatedStringLiteralToCh<u></u><u></u>arPtrConversion(<br>
+    const ImplicitConversionSequence &ICS) {<br>
+  return (ICS.isStandard() && ICS.Standard.<u></u>DeprecatedStringL<u></u>iteralToCharP<u></u>tr) ||<br>
+         (ICS.isUserDefined() &&<br>
+          ICS.UserDefined.Before.<u></u>Deprec<u></u>atedStringLiteralToCharP<u></u>tr);<br>
+}<br>
+<br>
 /// CompareImplicitConversionSeque<u></u><u></u>nces - Compare two implicit<br>
 /// conversion sequences to determine whether one is better than the<br>
 /// other or if they are indistinguishable (C++ 13.3.3.2).<br>
@@ -3333,6 +3335,32 @@ CompareImplicitConversionSeque<u></u><u></u>nces(Sema<br>
   //   described in 13.3.3.2, the ambiguous conversion sequence is<br>
   //   treated as a user-defined sequence that is indistinguishable<br>
   //   from any other user-defined conversion sequence.<br>
+<br>
+  // String literal to 'char *' conversion has been deprecated in C++03. It has<br>
+  // been removed from C++11. We still accept this conversion, if it happens at<br>
+  // the best viable function. Otherwise, this conversion is considered worse<br>
+  // than ellipsis conversion. Consider this as an extension; this is not in the<br>
+  // standard. For example:<br>
+  //<br>
+  // int &f(...);    // #1<br>
+  // void f(char*);  // #2<br>
+  // void g() { int &r = f("foo"); }<br>
+  //<br>
+  // In C++03, we pick #2 as the best viable function.<br>
+  // In C++11, we pick #1 as the best viable function, because ellipsis<br>
+  // conversion is better than string-literal to char* conversion (since there<br>
+  // is no such conversion in C++11). If there was no #1 at all or #1 couldn't<br>
+  // convert arguments, #2 would be the best viable function in C++11.<br>
+  // If the best viable function has this conversion, a warning will be issued<br>
+  // in C++03, or an ExtWarn (+SFINAE failure) will be issued in C++11.<br>
+<br>
+  if (S.getLangOpts().CPlusPlus11 && !S.getLangOpts().<u></u>WritableStrin<u></u>gs &&<br>
+      <u></u>hasDeprecatedStringLiteralToCh<u></u><u></u>arPtrConversion(ICS1) !=<br>
+      <u></u>hasDeprecatedStringLiteralToCh<u></u><u></u>arPtrConversion(ICS2))<br>
+    return hasDeprecatedStringLiteralToCh<u></u><u></u>arPtrConversion(ICS1)<br>
+               ? ImplicitConversionSequence::<u></u>Wo<u></u>rse<br>
+               : ImplicitConversionSequence::<u></u>Be<u></u>tter;<br>
+<br>
   if (ICS1.getKindRank() < ICS2.getKindRank())<br>
     return ImplicitConversionSequence::<u></u>Be<u></u>tter;<br>
   if (ICS2.getKindRank() < ICS1.getKindRank())<br>
@@ -4244,6 +4272,7 @@ TryReferenceInit(Sema &S, Expr *Init, Qu<br>
       ICS.Standard.<u></u>BindsImplicitObj<u></u>ectArgumentWit<u></u>houtRefQualifier = false;<br>
       ICS.Standard.<u></u>ObjCLifetimeConv<u></u>ersionBinding = ObjCLifetimeConversion;<br>
       ICS.Standard.CopyConstructor = 0;<br>
+      ICS.Standard.<u></u>DeprecatedString<u></u>LiteralToCharP<u></u>tr = false;<br>
<br>
       // Nothing more to do: the inaccessibility/ambiguity check for<br>
       // derived-to-base conversions is suppressed when we're<br>
@@ -4318,6 +4347,7 @@ TryReferenceInit(Sema &S, Expr *Init, Qu<br>
     ICS.Standard.<u></u>BindsImplicitObj<u></u>ectArgumentWit<u></u>houtRefQualifier = false;<br>
     ICS.Standard.<u></u>ObjCLifetimeConv<u></u>ersionBinding = ObjCLifetimeConversion;<br>
     ICS.Standard.CopyConstructor = 0;<br>
+    ICS.Standard.<u></u>DeprecatedString<u></u>LiteralToCharP<u></u>tr = false;<br>
     return ICS;<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/test/SemaCXX/cxx0x-<u></u>t<u></u>ype-convert-construct.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp?rev=199513&r1=199512&r2=199513&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>pr<u></u>oject/cfe/trunk/test/<u></u>SemaCXX/<u></u>cxx0x-type-convert-<u></u>construct.<u></u>cpp?rev=199513&r1=<u></u>199512&r2=<u></u>199513&view=diff</a><br>


==============================<u></u><u></u>==============================<u></u><u></u>==================<br>
--- cfe/trunk/test/SemaCXX/cxx0x-<u></u>t<u></u>ype-convert-construct.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/cxx0x-<u></u>t<u></u>ype-convert-construct.cpp Fri Jan 17 15:08:52 2014<br>
@@ -9,9 +9,9 @@ void f() {<br>
   Ustr = U"a UTF-32 string"; // expected-error {{assigning to 'char32_t *' from incompatible type 'const char32_t [16]'}}<br>
<br>
   char *Rstr;<br>
-  Rstr = R"foo(a raw string)foo"; // expected-warning{{conversion from string literal to 'char *' is deprecated}}<br>
+  Rstr = R"foo(a raw string)foo"; // expected-warning{{ISO C++11 does not allow conversion from string literal to 'char *'}}<br>
   wchar_t *LRstr;<br>
-  LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}}<br>
+  LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{ISO C++11 does not allow conversion from string literal to 'wchar_t *'}}<br>
   char *u8Rstr;<br>
   u8Rstr = u8R"foo(a UTF-8 raw string)foo"; // expected-error {{assigning to 'char *' from incompatible type 'const char [19]'}}<br>
   char16_t *uRstr;<br>
<br>
Modified: cfe/trunk/test/SemaCXX/<u></u>depreca<u></u>ted.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/deprecated.cpp?rev=199513&r1=199512&r2=199513&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>pr<u></u>oject/cfe/trunk/test/<u></u>SemaCXX/<u></u>deprecated.cpp?rev=<u></u>199513&r1=<u></u>199512&r2=199513&<u></u>view=diff</a><br>


==============================<u></u><u></u>==============================<u></u><u></u>==================<br>
--- cfe/trunk/test/SemaCXX/<u></u>depreca<u></u>ted.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/<u></u>depreca<u></u>ted.cpp Fri Jan 17 15:08:52 2014<br>
@@ -24,12 +24,15 @@ void stuff() {<br>
   register int m asm("rbx"); // no-warning<br>
<br>
   int k = to_int(n); // no-warning<br>
-<br>
   bool b;<br>
   ++b; // expected-warning {{incrementing expression of type bool is deprecated}}<br>
<br>
-  // FIXME: This is ill-formed in C++11.<br>
-  char *p = "foo"; // expected-warning {{conversion from string literal to 'char *' is deprecated}}<br>
+  char *p = "foo";<br>
+#if __cplusplus < 201103L<br>
+  // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}<br>
+#else<br>
+  // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}}<br>
+#endif<br>
 }<br>
<br>
 struct S { int n; };<br>
<br>
Modified: cfe/trunk/test/SemaCXX/<u></u>overloa<u></u>d-0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-0x.cpp?rev=199513&r1=199512&r2=199513&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>pr<u></u>oject/cfe/trunk/test/<u></u>SemaCXX/<u></u>overload-0x.cpp?rev=<u></u>199513&r1=<u></u>199512&r2=199513&<u></u>view=diff</a><br>


==============================<u></u><u></u>==============================<u></u><u></u>==================<br>
--- cfe/trunk/test/SemaCXX/<u></u>overloa<u></u>d-0x.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/<u></u>overloa<u></u>d-0x.cpp Fri Jan 17 15:08:52 2014<br>
@@ -1,7 +1,11 @@<br>
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s<br>
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s<br>
+// RUN: %clang_cc1 -fsyntax-only -verify %s<br>
<br>
 namespace test0 {<br>
-  struct A { // expected-note {{candidate function (the implicit copy assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}} expected-note {{candidate function (the implicit move assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}<br>


+  struct A { // expected-note {{candidate function (the implicit copy assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}<br>
+#if __cplusplus >= 201103L<br>
+  // expected-note@-2 {{candidate function (the implicit move assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}<br>
+#endif<br>
     A &operator=(void*); // expected-note {{candidate function not viable: 'this' argument has type 'const test0::A', but method is not marked const}}<br>
   };<br>
<br>
@@ -9,3 +13,79 @@ namespace test0 {<br>
     a = "help"; // expected-error {{no viable overloaded '='}}<br>
   }<br>
 }<br>
+<br>
+namespace PR16314 {<br>
+  void f(char*);<br>
+  int &f(...);<br>
+  void x()<br>
+  {<br>
+    int &n = f("foo");<br>
+#if __cplusplus < 201103L<br>
+    // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}<br>
+    // expected-error@-3 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'void'}}<br>
+#endif<br>
+  }<br>
+}<br>
+<br>
+namespace warn_if_best {<br>
+  int f(char *);<br>
+  void f(double);<br>
+  void x()<br>
+  {<br>
+    int n = f("foo");<br>
+#if __cplusplus < 201103L<br>
+    // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}<br>
+#else<br>
+    // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}}<br>
+#endif<br>
+  }<br>
+}<br>
+<br>
+namespace userdefined_vs_illformed {<br>
+  struct X { X(const char *); };<br>
+<br>
+  void *f(char *p); // best for C++03<br>
+  double f(X x);  // best for C++11<br>
+  void g()<br>
+  {<br>
+    double d = f("foo");<br>
+#if __cplusplus < 201103L<br>
+    // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}<br>
+    // expected-error@-3 {{cannot initialize a variable of type 'double' with an rvalue of type 'void *'}}<br>
+#endif<br>
+  }<br>
+}<br>
+<br>
+namespace sfinae_test {<br>
+  int f(int, char*);<br>
+<br>
+  template<int T><br>
+  struct S { typedef int type; };<br>
+<br>
+  template<><br>
+  struct S<sizeof(int)> { typedef void type; };<br>
+<br>
+  // C++11: SFINAE failure<br>
+  // C++03: ok<br>
+  template<typename T> int cxx11_ignored(T, typename S<sizeof(f(T(), "foo"))>::type *);<br>
+#if __cplusplus < 201103L<br>
+  // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}<br>
+#else<br>
+  // expected-note@-4 {{candidate template ignored: substitution failure}}<br>
+#endif<br>
+<br>
+  // C++11: better than latter<br>
+  // C++03: worse than latter<br>
+  template<typename T> void g(T, ...);<br>
+  template<typename T> int g(T, typename S<sizeof(f(T(), "foo"))>::type *);<br>
+#if __cplusplus < 201103L<br>
+  // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}<br>
+#endif<br>
+<br>
+  int a = cxx11_ignored(0, 0);<br>
+  int b = g(0, 0);<br>
+#if __cplusplus >= 201103L<br>
+  // expected-error@-3 {{no matching function for call to 'cxx11_ignored'}}<br>
+  // expected-error@-3 {{cannot initialize a variable of type 'int' with an rvalue of type 'void'}}<br>
+#endif<br>
+}<br>
<br>
Modified: cfe/trunk/unittests/<u></u>ASTMatcher<u></u>s/ASTMatchersTest.<u></u>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=199513&r1=199512&r2=199513&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>pr<u></u>oject/cfe/trunk/unittests/<u></u>ASTM<u></u>atchers/ASTMatchersTest.<u></u>cpp?<u></u>rev=199513&r1=199512&r2=<u></u>199513<u></u>&view=diff</a><br>


==============================<u></u><u></u>==============================<u></u><u></u>==================<br>
--- cfe/trunk/unittests/<u></u>ASTMatcher<u></u>s/ASTMatchersTest.<u></u>cpp (original)<br>
+++ cfe/trunk/unittests/<u></u>ASTMatcher<u></u>s/ASTMatchersTest.<u></u>cpp Fri Jan 17 15:08:52 2014<br>
@@ -2608,13 +2608,13 @@ TEST(ReinterpretCast, DoesNotMatchOtherC<br>
 }<br>
<br>
 TEST(FunctionalCast, MatchesSimpleCase) {<br>
-  std::string foo_class = "class Foo { public: Foo(char*); };";<br>
+  std::string foo_class = "class Foo { public: Foo(const char*); };";<br>
   EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",<br>
                       functionalCastExpr()));<br>
 }<br>
<br>
 TEST(FunctionalCast, DoesNotMatchOtherCasts) {<br>
-  std::string FooClass = "class Foo { public: Foo(char*); };";<br>
+  std::string FooClass = "class Foo { public: Foo(const char*); };";<br>
   EXPECT_TRUE(<br>
       notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",<br>
                  functionalCastExpr()));<br>
<br>
<br>
______________________________<u></u><u></u>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailm<u></u>an/listinfo/cfe-commits</a><br>
</blockquote>
</div></div><br>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div>