[PATCH] C++11: Reject string literal to non-const char * conversion
Ismail Pazarbasi
ismail.pazarbasi at gmail.com
Tue Nov 5 10:31:58 PST 2013
Compared to the previous revision, this revision issues a new ExtWarn instead of the existing Warning.
Hi rsmith,
http://llvm-reviews.chandlerc.com/D1965
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1965?vs=5328&id=5351#toc
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaOverload.cpp
test/SemaCXX/cxx0x-type-convert-construct.cpp
test/SemaCXX/deprecated.cpp
test/SemaCXX/overload-0x.cpp
unittests/ASTMatchers/ASTMatchersTest.cpp
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -4485,6 +4485,8 @@
InGroup<DiagGroup<"gnu-array-member-paren-init">>, DefaultError;
def warn_deprecated_string_literal_conversion : Warning<
"conversion from string literal to %0 is deprecated">, InGroup<DeprecatedWritableStr>;
+def ext_warn_deprecated_string_literal_conversion : ExtWarn<
+ "conversion from string literal to %0 is ill-formed in C++11">, InGroup<DeprecatedWritableStr>;
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">;
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -3020,9 +3020,13 @@
CK_NoOp, VK, /*BasePath=*/0, CCK).take();
if (SCS.DeprecatedStringLiteralToCharPtr &&
- !getLangOpts().WritableStrings)
- Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion)
- << ToType.getNonReferenceType();
+ !getLangOpts().WritableStrings) {
+ Diag(From->getLocStart(),
+ getLangOpts().CPlusPlus11
+ ? diag::ext_warn_deprecated_string_literal_conversion
+ : diag::warn_deprecated_string_literal_conversion)
+ << ToType.getNonReferenceType();
+ }
break;
}
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -1172,6 +1172,18 @@
return ICS;
}
+/// Checks whether conversion sequence is string literal to (non-const) char *
+/// in C++11 mode. -fwritable-strings still enables the conversion.
+static inline bool
+isIllFormedStringLiteralConversion(Sema &S,
+ const ImplicitConversionSequence &ICS) {
+ return (ICS.isStandard() && ICS.Standard.First == ICK_Array_To_Pointer &&
+ ICS.Standard.Second == ICK_Identity &&
+ ICS.Standard.Third == ICK_Qualification &&
+ ICS.Standard.DeprecatedStringLiteralToCharPtr &&
+ !S.getLangOpts().WritableStrings && S.getLangOpts().CPlusPlus11);
+}
+
/// TryImplicitConversion - Attempt to perform an implicit conversion
/// from the given expression (Expr) to the given type (ToType). This
/// function returns an implicit conversion sequence that can be used
@@ -1513,7 +1525,7 @@
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,7 +3271,7 @@
return ImplicitConversionSequence::Indistinguishable;
}
-
+
/// 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).
@@ -3283,9 +3295,14 @@
// treated as a user-defined sequence that is indistinguishable
// from any other user-defined conversion sequence.
if (ICS1.getKindRank() < ICS2.getKindRank())
- return ImplicitConversionSequence::Better;
+ return isIllFormedStringLiteralConversion(S, ICS1)
+ ? ImplicitConversionSequence::Worse
+ : ImplicitConversionSequence::Better;
+
if (ICS2.getKindRank() < ICS1.getKindRank())
- return ImplicitConversionSequence::Worse;
+ return isIllFormedStringLiteralConversion(S, ICS2)
+ ? ImplicitConversionSequence::Better
+ : ImplicitConversionSequence::Worse;
// The following checks require both conversion sequences to be of
// the same kind.
Index: test/SemaCXX/cxx0x-type-convert-construct.cpp
===================================================================
--- test/SemaCXX/cxx0x-type-convert-construct.cpp
+++ test/SemaCXX/cxx0x-type-convert-construct.cpp
@@ -9,9 +9,9 @@
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{{conversion from string literal to 'char *' is ill-formed in C++11}}
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{{conversion from string literal to 'wchar_t *' is ill-formed in C++11}}
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;
Index: test/SemaCXX/deprecated.cpp
===================================================================
--- test/SemaCXX/deprecated.cpp
+++ test/SemaCXX/deprecated.cpp
@@ -24,12 +24,15 @@
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 at -2 {{conversion from string literal to 'char *' is deprecated}}
+#else
+ // expected-warning at -4 {{conversion from string literal to 'char *' is ill-formed in C++11}}
+#endif
}
struct S { int n; };
Index: test/SemaCXX/overload-0x.cpp
===================================================================
--- test/SemaCXX/overload-0x.cpp
+++ test/SemaCXX/overload-0x.cpp
@@ -9,3 +9,22 @@
a = "help"; // expected-error {{no viable overloaded '='}}
}
}
+
+namespace PR16314 {
+ void f(char*);
+ int &f(...);
+ void x()
+ {
+ int &r = f("foo");
+ }
+}
+
+namespace warn_if_best {
+ void f(char *);
+ void f(double);
+ void x()
+ {
+ f("foo"); // expected-warning {{conversion from string literal to 'char *' is ill-formed in C++11}}
+ }
+}
+
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2583,13 +2583,13 @@
}
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()));
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1965.3.patch
Type: text/x-patch
Size: 7289 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131105/d123109c/attachment.bin>
More information about the cfe-commits
mailing list