C++: -Wwrite-strings: use location of string constant
authorDavid Malcolm <dmalcolm@redhat.com>
Fri, 17 Aug 2018 21:56:21 +0000 (21:56 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Fri, 17 Aug 2018 21:56:21 +0000 (21:56 +0000)
Consider:

extern int callee (const char *one, char *two, const char *three);

int test ()
{
  return callee ("first", "second", "third");
}

for which -Wwrite-strings was emitting:

Wwrite-strings.C: In function 'int test()':
Wwrite-strings.C:10:44: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
10 |   return callee ("first", "second", "third");
   |                                            ^

This patch fixes the warning so that it underlines the pertinent argument
at the callsite:

Wwrite-strings.C: In function 'int test()':
Wwrite-strings.C:10:27: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
10 |   return callee ("first", "second", "third");
   |                           ^~~~~~~~

Ideally we ought to also issue a "note" highlighting the pertinent
parameter within the decl, but that's not readily available, so I'm
saving it for another patch.

gcc/cp/ChangeLog:
* typeck.c (string_conv_p): Extract location from EXP and use it
in preference to input_location when issuing warnings.

gcc/testsuite/ChangeLog:
* g++.dg/conversion/Wwrite-strings.C: New test.

From-SVN: r263635

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/conversion/Wwrite-strings.C [new file with mode: 0644]

index 0b695907cf137ea6bc85198707581e395db9755c..d8be93089b4c6e555d5acad45f84d4b795c51e2a 100644 (file)
@@ -1,3 +1,8 @@
+2018-08-17  David Malcolm  <dmalcolm@redhat.com>
+
+       * typeck.c (string_conv_p): Extract location from EXP and use it
+       in preference to input_location when issuing warnings.
+
 2018-08-15  David Malcolm  <dmalcolm@redhat.com>
 
        * call.c: Include "gcc-rich-location.h".
index 64b3d583356c45c1ff4c3fba608525ed9142366c..8c13ae9b19ba18e18b7988a7ece16217d6c6732a 100644 (file)
@@ -2208,6 +2208,8 @@ string_conv_p (const_tree totype, const_tree exp, int warn)
       && !same_type_p (t, wchar_type_node))
     return 0;
 
+  location_t loc = EXPR_LOC_OR_LOC (exp, input_location);
+
   STRIP_ANY_LOCATION_WRAPPER (exp);
 
   if (TREE_CODE (exp) == STRING_CST)
@@ -2230,13 +2232,13 @@ string_conv_p (const_tree totype, const_tree exp, int warn)
   if (warn)
     {
       if (cxx_dialect >= cxx11)
-       pedwarn (input_location, OPT_Wwrite_strings,
+       pedwarn (loc, OPT_Wwrite_strings,
                 "ISO C++ forbids converting a string constant to %qT",
                 totype);
       else
-       warning (OPT_Wwrite_strings,
-                "deprecated conversion from string constant to %qT",
-                totype);
+       warning_at (loc, OPT_Wwrite_strings,
+                   "deprecated conversion from string constant to %qT",
+                   totype);
     }
 
   return 1;
index ea1f1fa6061fe98d77ebc289b0a6e00c57938b9d..b8677d729bc371a5478652e86c3da3829afc3530 100644 (file)
@@ -1,3 +1,7 @@
+2018-08-17  David Malcolm  <dmalcolm@redhat.com>
+
+       * g++.dg/conversion/Wwrite-strings.C: New test.
+
 2018-08-17  Sandra Loosemore  <sandra@codesourcery.com>
            Chung-Lin Tang  <cltang@codesourcery.com>
            Xianmiao Qu  <xianmiao_qu@c-sky.com>
diff --git a/gcc/testsuite/g++.dg/conversion/Wwrite-strings.C b/gcc/testsuite/g++.dg/conversion/Wwrite-strings.C
new file mode 100644 (file)
index 0000000..f6dbb15
--- /dev/null
@@ -0,0 +1,24 @@
+// { dg-options "-fdiagnostics-show-caret" }
+
+/* Verify that -Wwrite-strings underlines the string literal in question.  */
+
+extern int callee (const char *one, char *two, const char *three);
+
+int test_1 ()
+{
+  return callee ("first", "second", "third"); // { dg-warning "string constant to 'char\\*'" }
+  /* { dg-begin-multiline-output "" }
+   return callee ("first", "second", "third");
+                           ^~~~~~~~
+     { dg-end-multiline-output "" } */
+  // TODO: underline the pertinent param in the decl of callee
+}
+
+char *test_2 (void)
+{
+  return "foo"; // { dg-warning "string constant to 'char\\*'" }
+  /* { dg-begin-multiline-output "" }
+   return "foo";
+          ^~~~~
+     { dg-end-multiline-output "" } */
+}