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 Deprecated StringLiteralToCharPtr. 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/SemaE xprCXX.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_l iteral_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/SemaO verload.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/ASTM atchers/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
