From e489a7d3d397214a43d587d88378f3df642aba60 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sun, 28 Feb 2010 18:30:25 +0000 Subject: [PATCH] Warn about the deprecated string literal -> char* conversion. Fixes PR6428. llvm-svn: 97404 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 ++- clang/lib/Sema/SemaExprCXX.cpp | 5 +++++ clang/lib/Sema/SemaOverload.cpp | 10 +++++----- clang/lib/Sema/SemaOverload.h | 2 +- .../CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp | 5 +++-- clang/test/SemaCXX/dcl_init_aggr.cpp | 2 +- clang/test/SemaCXX/overload-call.cpp | 6 +++--- clang/test/SemaCXX/type-convert-construct.cpp | 4 ++-- 8 files changed, 22 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 91e3652ed5ed..9e5e9f6f8b1d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1779,7 +1779,8 @@ def err_typecheck_incomplete_array_needs_initializer : Error< def err_array_init_not_init_list : Error< "array initializer must be an initializer " "list%select{| or string literal}0">; - +def warn_deprecated_string_literal_conversion : Warning< + "conversion from string literal to %0 is deprecated">; def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">; def err_typecheck_sclass_fscope : Error< "illegal storage class on file-scoped variable">; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index daa4b5a98e49..23d52adf91a1 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1774,6 +1774,11 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, ImpCastExprToType(From, ToType.getNonReferenceType(), CastExpr::CK_NoOp, ToType->isLValueReferenceType()); + + if (SCS.DeprecatedStringLiteralToCharPtr) + Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion) + << ToType.getNonReferenceType(); + break; default: diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 784663108b65..ed0d137d806c 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -118,7 +118,7 @@ void StandardConversionSequence::setAsIdentityConversion() { First = ICK_Identity; Second = ICK_Identity; Third = ICK_Identity; - Deprecated = false; + DeprecatedStringLiteralToCharPtr = false; ReferenceBinding = false; DirectBinding = false; RRefBinding = false; @@ -549,7 +549,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, // Standard conversions (C++ [conv]) SCS.setAsIdentityConversion(); - SCS.Deprecated = false; + SCS.DeprecatedStringLiteralToCharPtr = false; SCS.IncompatibleObjC = false; SCS.setFromType(FromType); SCS.CopyConstructor = 0; @@ -592,7 +592,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, if (IsStringLiteralToNonConstPointerConversion(From, ToType)) { // This conversion is deprecated. (C++ D.4). - SCS.Deprecated = true; + SCS.DeprecatedStringLiteralToCharPtr = true; // For the purpose of ranking in overload resolution // (13.3.3.1.1), this conversion is considered an @@ -1993,7 +1993,7 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1, // the deprecated string literal array to pointer conversion. switch (Result) { case ImplicitConversionSequence::Better: - if (SCS1.Deprecated) + if (SCS1.DeprecatedStringLiteralToCharPtr) Result = ImplicitConversionSequence::Indistinguishable; break; @@ -2001,7 +2001,7 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1, break; case ImplicitConversionSequence::Worse: - if (SCS2.Deprecated) + if (SCS2.DeprecatedStringLiteralToCharPtr) Result = ImplicitConversionSequence::Indistinguishable; break; } diff --git a/clang/lib/Sema/SemaOverload.h b/clang/lib/Sema/SemaOverload.h index 62b096f703ad..58e416c87e59 100644 --- a/clang/lib/Sema/SemaOverload.h +++ b/clang/lib/Sema/SemaOverload.h @@ -117,7 +117,7 @@ namespace clang { /// Deprecated - Whether this the deprecated conversion of a /// string literal to a pointer to non-const character data /// (C++ 4.2p2). - bool Deprecated : 1; + bool DeprecatedStringLiteralToCharPtr : 1; /// IncompatibleObjC - Whether this is an Objective-C conversion /// that we should warn about (if we actually use it). diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp index 95f9640a0b43..dc79300af336 100644 --- a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp +++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp @@ -3,8 +3,9 @@ template X f(Y,Z); // expected-note {{candidate template ignored: couldn't infer template argument 'X'}} void g() { - f("aa",3.0); - f("aa",3.0); // Z is deduced to be double + f("aa",3.0); // expected-warning{{conversion from string literal to 'char *' is deprecated}} + f("aa",3.0); // Z is deduced to be double \ + // expected-warning{{conversion from string literal to 'char *' is deprecated}} f("aa",3.0); // Y is deduced to be char*, and // Z is deduced to be double f("aa",3.0); // expected-error{{no matching}} diff --git a/clang/test/SemaCXX/dcl_init_aggr.cpp b/clang/test/SemaCXX/dcl_init_aggr.cpp index 861eb3dcb163..461c60b5bbc1 100644 --- a/clang/test/SemaCXX/dcl_init_aggr.cpp +++ b/clang/test/SemaCXX/dcl_init_aggr.cpp @@ -38,7 +38,7 @@ char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-error{{excess elements in ar // C++ [dcl.init.aggr]p7 struct TooFew { int a; char* b; int c; }; -TooFew too_few = { 1, "asdf" }; // okay +TooFew too_few = { 1, "asdf" }; // expected-warning{{conversion from string literal to 'char *' is deprecated}} struct NoDefaultConstructor { // expected-note 3 {{candidate constructor (the implicit copy constructor)}} \ // expected-note{{declared here}} diff --git a/clang/test/SemaCXX/overload-call.cpp b/clang/test/SemaCXX/overload-call.cpp index 364011c91728..77e0908ef46d 100644 --- a/clang/test/SemaCXX/overload-call.cpp +++ b/clang/test/SemaCXX/overload-call.cpp @@ -53,7 +53,7 @@ int* k(char*); double* k(bool); void test_k() { - int* ip1 = k("foo"); + int* ip1 = k("foo"); // expected-warning{{conversion from string literal to 'char *' is deprecated}} double* dp1 = k(L"foo"); } @@ -61,7 +61,7 @@ int* l(wchar_t*); double* l(bool); void test_l() { - int* ip1 = l(L"foo"); + int* ip1 = l(L"foo"); // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}} double* dp1 = l("foo"); } @@ -79,7 +79,7 @@ class E; void test_n(E* e) { char ca[7]; int* ip1 = n(ca); - int* ip2 = n("foo"); + int* ip2 = n("foo"); // expected-warning{{conversion from string literal to 'char *' is deprecated}} float fa[7]; double* dp1 = n(fa); diff --git a/clang/test/SemaCXX/type-convert-construct.cpp b/clang/test/SemaCXX/type-convert-construct.cpp index d786a9a8a6fc..8f92a035dc7d 100644 --- a/clang/test/SemaCXX/type-convert-construct.cpp +++ b/clang/test/SemaCXX/type-convert-construct.cpp @@ -11,7 +11,7 @@ void f() { int *p; bool v6 = T(0) == p; char *str; - str = "a string"; + str = "a string"; // expected-warning{{conversion from string literal to 'char *' is deprecated}} wchar_t *wstr; - wstr = L"a wide string"; + wstr = L"a wide string"; // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}} }