I have fixed the problem with DeprecatedStringLiteralToCharPtr initialization. Could you please review changes in r199988 and r199997?
Thanks! On Fri, Jan 24, 2014 at 10:41 AM, Ismail Pazarbasi <[email protected]> wrote: > I didn't know this was failing, sorry for breakage. I will try to > update the patch. If that can't be done quickly, I can check entire > conversion sequence, which was working. > > On Fri, Jan 24, 2014 at 10:02 AM, Evgeniy Stepanov > <[email protected]> wrote: >> The bot was down until less than a day ago, so no one actually new >> about the issue. I guess it's ok to wait another day. >> >> >> On Fri, Jan 24, 2014 at 12:55 PM, Chandler Carruth <[email protected]> >> wrote: >>> Can we revert until a fix is ready? 7 days with msan failures is too many. >>> >>> >>> On Thu, Jan 23, 2014 at 8:08 PM, Richard Smith <[email protected]> wrote: >>>> >>>> Looks like the msan build bot has found a bug here: >>>> >>>> >>>> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/1844/steps/annotate/logs/stdio >>>> >>>> It appears that some path through the code doesn't initialize >>>> DeprecatedStringLiteralToCharPtr. >>>> >>>> On Fri Jan 17 2014 at 1:15:20 PM, Ismail Pazarbasi >>>> <[email protected]> wrote: >>>> >>>> Author: ismailp >>>> Date: Fri Jan 17 15:08:52 2014 >>>> New Revision: 199513 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=199513&view=rev >>>> Log: >>>> Fix string-literal to char* conversion in overload resolution for C++11 >>>> >>>> String literal to char* conversion is deprecated in C++03, and is removed >>>> in >>>> C++11. We still accept this conversion in C++11 mode as an extension, if >>>> we find >>>> it in the best viable function. >>>> >>>> >>>> Modified: >>>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >>>> cfe/trunk/lib/Sema/SemaExprCXX.cpp >>>> cfe/trunk/lib/Sema/SemaOverload.cpp >>>> cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp >>>> cfe/trunk/test/SemaCXX/deprecated.cpp >>>> cfe/trunk/test/SemaCXX/overload-0x.cpp >>>> cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp >>>> >>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=199513&r1=199512&r2=199513&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) >>>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 17 >>>> 15:08:52 2014 >>>> @@ -4534,6 +4534,9 @@ def ext_array_init_parens : ExtWarn< >>>> def warn_deprecated_string_literal_conversion : Warning< >>>> "conversion from string literal to %0 is deprecated">, >>>> InGroup<CXX11CompatDeprecatedWritableStr>; >>>> +def ext_deprecated_string_literal_conversion : ExtWarn< >>>> + "ISO C++11 does not allow conversion from string literal to %0">, >>>> + InGroup<CXX11CompatDeprecatedWritableStr>, SFINAEFailure; >>>> def warn_deprecated_string_literal_conversion_c : Warning< >>>> "dummy warning to enable -fconst-strings">, >>>> InGroup<DeprecatedWritableStr>, DefaultIgnore; >>>> def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">; >>>> >>>> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=199513&r1=199512&r2=199513&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) >>>> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Jan 17 15:08:52 2014 >>>> @@ -3058,9 +3058,12 @@ Sema::PerformImplicitConversion(Expr *Fr >>>> CK_NoOp, VK, /*BasePath=*/0, CCK).take(); >>>> >>>> if (SCS.DeprecatedStringLiteralToCharPtr && >>>> - !getLangOpts().WritableStrings) >>>> - Diag(From->getLocStart(), >>>> diag::warn_deprecated_string_literal_conversion) >>>> + !getLangOpts().WritableStrings) { >>>> + Diag(From->getLocStart(), getLangOpts().CPlusPlus11 >>>> + ? diag::ext_deprecated_string_literal_conversion >>>> + : diag::warn_deprecated_string_literal_conversion) >>>> << ToType.getNonReferenceType(); >>>> + } >>>> >>>> break; >>>> } >>>> >>>> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=199513&r1=199512&r2=199513&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) >>>> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Jan 17 15:08:52 2014 >>>> @@ -1443,7 +1443,6 @@ static bool IsStandardConversion(Sema &S >>>> >>>> // Standard conversions (C++ [conv]) >>>> SCS.setAsIdentityConversion(); >>>> - SCS.DeprecatedStringLiteralToCharPtr = false; >>>> SCS.IncompatibleObjC = false; >>>> SCS.setFromType(FromType); >>>> SCS.CopyConstructor = 0; >>>> @@ -1542,7 +1541,7 @@ static bool IsStandardConversion(Sema &S >>>> FromType = S.Context.getArrayDecayedType(FromType); >>>> >>>> if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) { >>>> - // This conversion is deprecated. (C++ D.4). >>>> + // This conversion is deprecated in C++03 (D.4) >>>> SCS.DeprecatedStringLiteralToCharPtr = true; >>>> >>>> // For the purpose of ranking in overload resolution >>>> @@ -3259,18 +3258,15 @@ Sema::DiagnoseMultipleUserDefinedConvers >>>> IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined, >>>> CandidateSet, false, false); >>>> if (OvResult == OR_Ambiguous) >>>> - Diag(From->getLocStart(), >>>> - diag::err_typecheck_ambiguous_condition) >>>> - << From->getType() << ToType << From->getSourceRange(); >>>> + Diag(From->getLocStart(), diag::err_typecheck_ambiguous_condition) >>>> + << From->getType() << ToType << From->getSourceRange(); >>>> else if (OvResult == OR_No_Viable_Function && !CandidateSet.empty()) { >>>> if (!RequireCompleteType(From->getLocStart(), ToType, >>>> - >>>> diag::err_typecheck_nonviable_condition_incomplete, >>>> + >>>> diag::err_typecheck_nonviable_condition_incomplete, >>>> From->getType(), From->getSourceRange())) >>>> - Diag(From->getLocStart(), >>>> - diag::err_typecheck_nonviable_condition) >>>> - << From->getType() << From->getSourceRange() << ToType; >>>> - } >>>> - else >>>> + Diag(From->getLocStart(), diag::err_typecheck_nonviable_condition) >>>> + << From->getType() << From->getSourceRange() << ToType; >>>> + } else >>>> return false; >>>> CandidateSet.NoteCandidates(*this, OCD_AllCandidates, From); >>>> return true; >>>> @@ -3280,37 +3276,43 @@ Sema::DiagnoseMultipleUserDefinedConvers >>>> /// of two user-defined conversion sequences to determine whether any >>>> ordering >>>> /// is possible. >>>> static ImplicitConversionSequence::CompareKind >>>> -compareConversionFunctions(Sema &S, >>>> - FunctionDecl *Function1, >>>> +compareConversionFunctions(Sema &S, FunctionDecl *Function1, >>>> FunctionDecl *Function2) { >>>> if (!S.getLangOpts().ObjC1 || !S.getLangOpts().CPlusPlus11) >>>> return ImplicitConversionSequence::Indistinguishable; >>>> - >>>> + >>>> // Objective-C++: >>>> // If both conversion functions are implicitly-declared conversions >>>> from >>>> - // a lambda closure type to a function pointer and a block pointer, >>>> + // a lambda closure type to a function pointer and a block pointer, >>>> // respectively, always prefer the conversion to a function pointer, >>>> // because the function pointer is more lightweight and is more >>>> likely >>>> // to keep code working. >>>> CXXConversionDecl *Conv1 = dyn_cast<CXXConversionDecl>(Function1); >>>> if (!Conv1) >>>> return ImplicitConversionSequence::Indistinguishable; >>>> - >>>> + >>>> CXXConversionDecl *Conv2 = dyn_cast<CXXConversionDecl>(Function2); >>>> if (!Conv2) >>>> return ImplicitConversionSequence::Indistinguishable; >>>> - >>>> + >>>> if (Conv1->getParent()->isLambda() && Conv2->getParent()->isLambda()) { >>>> bool Block1 = Conv1->getConversionType()->isBlockPointerType(); >>>> bool Block2 = Conv2->getConversionType()->isBlockPointerType(); >>>> if (Block1 != Block2) >>>> - return Block1? ImplicitConversionSequence::Worse >>>> - : ImplicitConversionSequence::Better; >>>> + return Block1 ? ImplicitConversionSequence::Worse >>>> + : ImplicitConversionSequence::Better; >>>> } >>>> >>>> return ImplicitConversionSequence::Indistinguishable; >>>> } >>>> - >>>> + >>>> +static bool hasDeprecatedStringLiteralToCharPtrConversion( >>>> + const ImplicitConversionSequence &ICS) { >>>> + return (ICS.isStandard() && >>>> ICS.Standard.DeprecatedStringLiteralToCharPtr) || >>>> + (ICS.isUserDefined() && >>>> + ICS.UserDefined.Before.DeprecatedStringLiteralToCharPtr); >>>> +} >>>> + >>>> /// CompareImplicitConversionSequences - Compare two implicit >>>> /// conversion sequences to determine whether one is better than the >>>> /// other or if they are indistinguishable (C++ 13.3.3.2). >>>> @@ -3333,6 +3335,32 @@ CompareImplicitConversionSequences(Sema >>>> // described in 13.3.3.2, the ambiguous conversion sequence is >>>> // treated as a user-defined sequence that is indistinguishable >>>> // from any other user-defined conversion sequence. >>>> + >>>> + // String literal to 'char *' conversion has been deprecated in C++03. >>>> It has >>>> + // been removed from C++11. We still accept this conversion, if it >>>> happens at >>>> + // the best viable function. Otherwise, this conversion is considered >>>> worse >>>> + // than ellipsis conversion. Consider this as an extension; this is not >>>> in the >>>> + // standard. For example: >>>> + // >>>> + // int &f(...); // #1 >>>> + // void f(char*); // #2 >>>> + // void g() { int &r = f("foo"); } >>>> + // >>>> + // In C++03, we pick #2 as the best viable function. >>>> + // In C++11, we pick #1 as the best viable function, because ellipsis >>>> + // conversion is better than string-literal to char* conversion (since >>>> there >>>> + // is no such conversion in C++11). If there was no #1 at all or #1 >>>> couldn't >>>> + // convert arguments, #2 would be the best viable function in C++11. >>>> + // If the best viable function has this conversion, a warning will be >>>> issued >>>> + // in C++03, or an ExtWarn (+SFINAE failure) will be issued in C++11. >>>> + >>>> + if (S.getLangOpts().CPlusPlus11 && !S.getLangOpts().WritableStrings && >>>> + hasDeprecatedStringLiteralToCharPtrConversion(ICS1) != >>>> + hasDeprecatedStringLiteralToCharPtrConversion(ICS2)) >>>> + return hasDeprecatedStringLiteralToCharPtrConversion(ICS1) >>>> + ? ImplicitConversionSequence::Worse >>>> + : ImplicitConversionSequence::Better; >>>> + >>>> if (ICS1.getKindRank() < ICS2.getKindRank()) >>>> return ImplicitConversionSequence::Better; >>>> if (ICS2.getKindRank() < ICS1.getKindRank()) >>>> @@ -4244,6 +4272,7 @@ TryReferenceInit(Sema &S, Expr *Init, Qu >>>> ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = >>>> false; >>>> ICS.Standard.ObjCLifetimeConversionBinding = >>>> ObjCLifetimeConversion; >>>> ICS.Standard.CopyConstructor = 0; >>>> + ICS.Standard.DeprecatedStringLiteralToCharPtr = false; >>>> >>>> // Nothing more to do: the inaccessibility/ambiguity check for >>>> // derived-to-base conversions is suppressed when we're >>>> @@ -4318,6 +4347,7 @@ TryReferenceInit(Sema &S, Expr *Init, Qu >>>> ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false; >>>> ICS.Standard.ObjCLifetimeConversionBinding = ObjCLifetimeConversion; >>>> ICS.Standard.CopyConstructor = 0; >>>> + ICS.Standard.DeprecatedStringLiteralToCharPtr = false; >>>> return ICS; >>>> } >>>> >>>> >>>> Modified: cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp?rev=199513&r1=199512&r2=199513&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp (original) >>>> +++ cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp Fri Jan 17 >>>> 15:08:52 2014 >>>> @@ -9,9 +9,9 @@ void f() { >>>> Ustr = U"a UTF-32 string"; // expected-error {{assigning to 'char32_t >>>> *' from incompatible type 'const char32_t [16]'}} >>>> >>>> char *Rstr; >>>> - Rstr = R"foo(a raw string)foo"; // expected-warning{{conversion from >>>> string literal to 'char *' is deprecated}} >>>> + Rstr = R"foo(a raw string)foo"; // expected-warning{{ISO C++11 does not >>>> allow conversion from string literal to 'char *'}} >>>> wchar_t *LRstr; >>>> - LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{conversion >>>> from string literal to 'wchar_t *' is deprecated}} >>>> + LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{ISO C++11 >>>> does not allow conversion from string literal to 'wchar_t *'}} >>>> char *u8Rstr; >>>> u8Rstr = u8R"foo(a UTF-8 raw string)foo"; // expected-error {{assigning >>>> to 'char *' from incompatible type 'const char [19]'}} >>>> char16_t *uRstr; >>>> >>>> Modified: cfe/trunk/test/SemaCXX/deprecated.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/deprecated.cpp?rev=199513&r1=199512&r2=199513&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/test/SemaCXX/deprecated.cpp (original) >>>> +++ cfe/trunk/test/SemaCXX/deprecated.cpp Fri Jan 17 15:08:52 2014 >>>> @@ -24,12 +24,15 @@ void stuff() { >>>> register int m asm("rbx"); // no-warning >>>> >>>> int k = to_int(n); // no-warning >>>> - >>>> bool b; >>>> ++b; // expected-warning {{incrementing expression of type bool is >>>> deprecated}} >>>> >>>> - // FIXME: This is ill-formed in C++11. >>>> - char *p = "foo"; // expected-warning {{conversion from string literal >>>> to 'char *' is deprecated}} >>>> + char *p = "foo"; >>>> +#if __cplusplus < 201103L >>>> + // expected-warning@-2 {{conversion from string literal to 'char *' is >>>> deprecated}} >>>> +#else >>>> + // expected-warning@-4 {{ISO C++11 does not allow conversion from >>>> string literal to 'char *'}} >>>> +#endif >>>> } >>>> >>>> struct S { int n; }; >>>> >>>> Modified: cfe/trunk/test/SemaCXX/overload-0x.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-0x.cpp?rev=199513&r1=199512&r2=199513&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/test/SemaCXX/overload-0x.cpp (original) >>>> +++ cfe/trunk/test/SemaCXX/overload-0x.cpp Fri Jan 17 15:08:52 2014 >>>> @@ -1,7 +1,11 @@ >>>> -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s >>>> +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s >>>> +// RUN: %clang_cc1 -fsyntax-only -verify %s >>>> >>>> namespace test0 { >>>> - 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}} >>>> + 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}} >>>> +#if __cplusplus >= 201103L >>>> + // 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}} >>>> +#endif >>>> A &operator=(void*); // expected-note {{candidate function not >>>> viable: 'this' argument has type 'const test0::A', but method is not marked >>>> const}} >>>> }; >>>> >>>> @@ -9,3 +13,79 @@ namespace test0 { >>>> a = "help"; // expected-error {{no viable overloaded '='}} >>>> } >>>> } >>>> + >>>> +namespace PR16314 { >>>> + void f(char*); >>>> + int &f(...); >>>> + void x() >>>> + { >>>> + int &n = f("foo"); >>>> +#if __cplusplus < 201103L >>>> + // expected-warning@-2 {{conversion from string literal to 'char *' >>>> is deprecated}} >>>> + // expected-error@-3 {{non-const lvalue reference to type 'int' >>>> cannot bind to a temporary of type 'void'}} >>>> +#endif >>>> + } >>>> +} >>>> + >>>> +namespace warn_if_best { >>>> + int f(char *); >>>> + void f(double); >>>> + void x() >>>> + { >>>> + int n = f("foo"); >>>> +#if __cplusplus < 201103L >>>> + // expected-warning@-2 {{conversion from string literal to 'char *' >>>> is deprecated}} >>>> +#else >>>> + // expected-warning@-4 {{ISO C++11 does not allow conversion from >>>> string literal to 'char *'}} >>>> +#endif >>>> + } >>>> +} >>>> + >>>> +namespace userdefined_vs_illformed { >>>> + struct X { X(const char *); }; >>>> + >>>> + void *f(char *p); // best for C++03 >>>> + double f(X x); // best for C++11 >>>> + void g() >>>> + { >>>> + double d = f("foo"); >>>> +#if __cplusplus < 201103L >>>> + // expected-warning@-2 {{conversion from string literal to 'char *' >>>> is deprecated}} >>>> + // expected-error@-3 {{cannot initialize a variable of type 'double' >>>> with an rvalue of type 'void *'}} >>>> +#endif >>>> + } >>>> +} >>>> + >>>> +namespace sfinae_test { >>>> + int f(int, char*); >>>> + >>>> + template<int T> >>>> + struct S { typedef int type; }; >>>> + >>>> + template<> >>>> + struct S<sizeof(int)> { typedef void type; }; >>>> + >>>> + // C++11: SFINAE failure >>>> + // C++03: ok >>>> + template<typename T> int cxx11_ignored(T, typename S<sizeof(f(T(), >>>> "foo"))>::type *); >>>> +#if __cplusplus < 201103L >>>> + // expected-warning@-2 {{conversion from string literal to 'char *' is >>>> deprecated}} >>>> +#else >>>> + // expected-note@-4 {{candidate template ignored: substitution >>>> failure}} >>>> +#endif >>>> + >>>> + // C++11: better than latter >>>> + // C++03: worse than latter >>>> + template<typename T> void g(T, ...); >>>> + template<typename T> int g(T, typename S<sizeof(f(T(), "foo"))>::type >>>> *); >>>> +#if __cplusplus < 201103L >>>> + // expected-warning@-2 {{conversion from string literal to 'char *' is >>>> deprecated}} >>>> +#endif >>>> + >>>> + int a = cxx11_ignored(0, 0); >>>> + int b = g(0, 0); >>>> +#if __cplusplus >= 201103L >>>> + // expected-error@-3 {{no matching function for call to >>>> 'cxx11_ignored'}} >>>> + // expected-error@-3 {{cannot initialize a variable of type 'int' with >>>> an rvalue of type 'void'}} >>>> +#endif >>>> +} >>>> >>>> Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=199513&r1=199512&r2=199513&view=diff >>>> >>>> ============================================================================== >>>> --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original) >>>> +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Fri Jan 17 >>>> 15:08:52 2014 >>>> @@ -2608,13 +2608,13 @@ TEST(ReinterpretCast, DoesNotMatchOtherC >>>> } >>>> >>>> TEST(FunctionalCast, MatchesSimpleCase) { >>>> - std::string foo_class = "class Foo { public: Foo(char*); };"; >>>> + std::string foo_class = "class Foo { public: Foo(const char*); };"; >>>> EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello >>>> world\"); }", >>>> functionalCastExpr())); >>>> } >>>> >>>> TEST(FunctionalCast, DoesNotMatchOtherCasts) { >>>> - std::string FooClass = "class Foo { public: Foo(char*); };"; >>>> + std::string FooClass = "class Foo { public: Foo(const char*); };"; >>>> EXPECT_TRUE( >>>> notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; >>>> }", >>>> functionalCastExpr())); >>>> >>>> >>>> _______________________________________________ >>>> cfe-commits mailing list >>>> [email protected] >>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >>>> >>>> >>>> _______________________________________________ >>>> cfe-commits mailing list >>>> [email protected] >>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >>>> >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> [email protected] >>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >>> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
