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
