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

Richard Smith richard at metafoo.co.uk
Wed Nov 13 18:07:28 PST 2013



================
Comment at: include/clang/Basic/DiagnosticSemaKinds.td:4493-4496
@@ -4492,2 +4492,6 @@
   "conversion from string literal to %0 is deprecated">, InGroup<DeprecatedWritableStr>;
+def ext_deprecated_string_literal_conversion : ExtWarn<
+  "conversion from string literal to %0 is ill-formed in C++11">, InGroup<DeprecatedWritableStr>;
+def err_deprecated_string_literal_conversion : Error<
+  "conversion from string literal to %0 is ill-formed in C++11">;
 def warn_deprecated_string_literal_conversion_c : Warning<
----------------
Since the last revision of your patch we've added a new way to do this. Add `SFINAEFailure` to the `ext_` diagnostic and drop the `err_` one:

    def ext_deprecated_string_literal_conversion : ExtWarn<
      "conversion from string literal to %0 is ill-formed in C++11">,
      InGroup<DeprecatedWritableStr>, SFINAEFailure;

================
Comment at: lib/Sema/SemaOverload.cpp:1152
@@ -1151,2 +1151,3 @@
         ICS.Standard.CopyConstructor = Constructor;
+        ICS.Standard.DeprecatedStringLiteralToCharPtr = false;
         if (ToCanon != FromCanon)
----------------
This is redundant; `StandardConversionSequence::setAsIdentityConversion` already does this.

================
Comment at: lib/Sema/SemaOverload.cpp:1245
@@ -1243,2 +1244,3 @@
     ICS.Standard.setAllToTypes(ToType);
+    ICS.Standard.DeprecatedStringLiteralToCharPtr = false;
 
----------------
Likewise.

================
Comment at: lib/Sema/SemaOverload.cpp:2987
@@ -2984,2 +2986,3 @@
     User.FoundConversionFunction = Best->FoundDecl;
+    User.Before.DeprecatedStringLiteralToCharPtr = false;
     User.After.setAsIdentityConversion();
----------------
Likewise.

================
Comment at: lib/Sema/SemaOverload.cpp:2991
@@ -2987,2 +2990,3 @@
     User.After.setAllToTypes(ToType);
+    User.After.DeprecatedStringLiteralToCharPtr = false;
     return OR_Success;
----------------
Likewise.

================
Comment at: lib/Sema/SemaOverload.cpp:3183
@@ -3178,2 +3182,3 @@
         User.Before.setAsIdentityConversion();
+        User.Before.DeprecatedStringLiteralToCharPtr = false;
       } else {
----------------
Likewise.

================
Comment at: lib/Sema/SemaOverload.cpp:3198
@@ -3192,2 +3197,3 @@
       User.After.setAllToTypes(ToType);
+      User.After.DeprecatedStringLiteralToCharPtr = false;
       return OR_Success;
----------------
Likewise.

================
Comment at: lib/Sema/SemaOverload.cpp:4419
@@ -4397,2 +4418,3 @@
     ICS.Standard.ObjCLifetimeConversionBinding = false;
+    ICS.Standard.DeprecatedStringLiteralToCharPtr = false;
   } else if (ICS.isUserDefined()) {
----------------
This looks wrong: if `TryImplicitConversion` performed a deprecated conversion to `char*`, we still have one in this conversion sequence. This might matter for a case like binding a `'char *const &'` to a string literal.

================
Comment at: lib/Sema/SemaOverload.cpp:4547
@@ -4523,2 +4546,3 @@
       Result.UserDefined.Before.setAllToTypes(QualType());
+      Result.UserDefined.Before.DeprecatedStringLiteralToCharPtr = false;
 
----------------
This is redundant.

================
Comment at: lib/Sema/SemaOverload.cpp:4552
@@ -4527,2 +4551,3 @@
       Result.UserDefined.After.setAllToTypes(ToType);
+      Result.UserDefined.After.DeprecatedStringLiteralToCharPtr = false;
       Result.UserDefined.ConversionFunction = 0;
----------------
Likewise.

================
Comment at: lib/Sema/SemaOverload.cpp:4645
@@ -4619,2 +4644,3 @@
       Result.Standard.setAllToTypes(ToType);
+      Result.Standard.DeprecatedStringLiteralToCharPtr = false;
     }
----------------
Likewise.

================
Comment at: lib/Sema/SemaOverload.cpp:4808
@@ -4781,2 +4807,3 @@
     = (Method->getRefQualifier() == RQ_None);
+  ICS.Standard.DeprecatedStringLiteralToCharPtr = false;
   return ICS;
----------------
Likewise.

================
Comment at: lib/Sema/SemaOverload.cpp:3330
@@ +3329,3 @@
+
+  if (S.getLangOpts().CPlusPlus11 && !S.getLangOpts().WritableStrings &&
+      hasDeprecatedStringLiteralToCharPtrConversion(ICS1) !=
----------------
Please add a brief comment before this explaining that the deprecated conversion is ill-formed in c++11, so we rank any conversion sequence that uses it as worse than any sequence that does not.

================
Comment at: test/SemaCXX/overload-0x.cpp:22-24
@@ +21,5 @@
+  {
+    // CXX03: call void @_ZN7PR163141fEPc
+    // CXX11: call i32* (...)* @_ZN7PR163141fEz
+    f("foo");
+#if __cplusplus < 201103L
----------------
Please use a syntax-only test for this, rather than an IR generation test. For instance:

    int &r = f("foo");
  #if __cplusplus < 201103L
    // expected-warning at -2 {{deprecated}}
    // expected-error at -3 {{cannot bind}}
  #endif


================
Comment at: test/SemaCXX/overload-0x.cpp:42
@@ +41,3 @@
+#else
+    // expected-warning at -4 {{warning: conversion from string literal to 'char *' is deprecated}}
+#endif
----------------
This won't work: "warning: " is not part of the string that -verify checks.

================
Comment at: lib/Sema/SemaExprCXX.cpp:3039
@@ +3038,3 @@
+          getLangOpts().CPlusPlus11
+              ? (isSFINAEContext()
+                     ? diag::err_deprecated_string_literal_conversion
----------------
Please add a test for the case where this happens in a SFINAE context. For instance:

  int f(int, char*);
  template<typename T> void g(T, decltype(f(T{}, "foo")));
  template<typename T> int &g(...);
  int &r = g(0, 0); // ok in c++11, picks g(...) because g<int> has a substitution failure

================
Comment at: include/clang/Basic/DiagnosticSemaKinds.td:4494
@@ +4493,3 @@
+def ext_deprecated_string_literal_conversion : ExtWarn<
+  "conversion from string literal to %0 is ill-formed in C++11">, InGroup<DeprecatedWritableStr>;
+def err_deprecated_string_literal_conversion : Error<
----------------
We don't phrase warnings this way elsewhere in the compiler. For consistency, word this as:

  "ISO C++11 does not allow conversion from string literal to %0"


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



More information about the cfe-commits mailing list