[PATCH] C++11: Reject string literal to non-const char * conversion

Ismail Pazarbasi ismail.pazarbasi at gmail.com
Thu Oct 17 15:49:06 PDT 2013


Hi rsmith,

Conversion of string literals to non-const char* is deprecated in C++03, and is ill-formed in C++11.

This patch also fixes PR16314.

http://llvm-reviews.chandlerc.com/D1965

Files:
  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: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -1513,7 +1513,11 @@
     FromType = S.Context.getArrayDecayedType(FromType);
 
     if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) {
-      // This conversion is deprecated. (C++ D.4).
+      // This conversion is ill-formed as of C++11.
+      if (S.getLangOpts().CPlusPlus11)
+        return false;
+
+      // This conversion is deprecated in C++03 (D.4)
       SCS.DeprecatedStringLiteralToCharPtr = true;
 
       // For the purpose of ranking in overload resolution
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-error {{assigning to 'char *' from incompatible type 'const char [13]'}}
   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-error {{assigning to 'wchar_t *' from incompatible type 'const wchar_t [18]'}}
   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
@@ -28,8 +28,11 @@
   bool b;
   ++b; // expected-warning {{incrementing expression of type bool is deprecated}}
 
-  // FIXME: This is ill-formed in C++11.
+#if __cplusplus < 201103L
   char *p = "foo"; // expected-warning {{conversion from string literal to 'char *' is deprecated}}
+#else
+  char *p = "foo"; // expected-error {{cannot initialize a variable of type 'char *' with an lvalue of type 'const char [4]'}}
+#endif
 }
 
 struct S { int n; };
Index: test/SemaCXX/overload-0x.cpp
===================================================================
--- test/SemaCXX/overload-0x.cpp
+++ test/SemaCXX/overload-0x.cpp
@@ -9,3 +9,12 @@
     a = "help"; // expected-error {{no viable overloaded '='}}
   }
 }
+
+namespace PR16314 {
+  void f(char*);
+  int &f(...);
+  void x()
+  {
+    int &r = f("foo");
+  }
+}
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2583,13 +2583,15 @@
 }
 
 TEST(FunctionalCast, MatchesSimpleCase) {
+  // ill-formed in C++11
   std::string foo_class = "class Foo { public: Foo(char*); };";
-  EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
-                      functionalCastExpr()));
+  EXPECT_TRUE(matchesConditionally(foo_class +
+                                   "void r() { Foo f = Foo(\"hello world\"); }",
+                      functionalCastExpr(), true, "-std=c++98"));
 }
 
 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.1.patch
Type: text/x-patch
Size: 3714 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131017/5287c567/attachment.bin>


More information about the cfe-commits mailing list