diff mbox series

[v2] C/C++: add hints for strerror

Message ID Zd6IuoANFHQcMg-H@dj3ntoo
State New
Headers show
Series [v2] C/C++: add hints for strerror | expand

Commit Message

Oskari Pirhonen Feb. 28, 2024, 1:13 a.m. UTC
Add proper hints for implicit declaration of strerror.

The results could be confusing depending on the other included headers.
These example messages are from compiling a trivial program to print the
string for an errno value. It only includes stdio.h (cstdio for C++).

Before:
$ /tmp/gcc-master/bin/gcc test.c -o test_c
test.c: In function ‘main’:
test.c:4:20: warning: implicit declaration of function ‘strerror’; did you mean ‘perror’? [-Wimplicit-function-declaration]
    4 |     printf("%s\n", strerror(0));
      |                    ^~~~~~~~
      |                    perror

$ /tmp/gcc-master/bin/g++ test.cpp -o test_cpp
test.cpp: In function ‘int main()’:
test.cpp:4:20: error: ‘strerror’ was not declared in this scope; did you mean ‘stderr’?
    4 |     printf("%s\n", strerror(0));
      |                    ^~~~~~~~
      |                    stderr

After:
$ /tmp/gcc-known-headers/bin/gcc test.c -o test_c
test.c: In function ‘main’:
test.c:4:20: warning: implicit declaration of function ‘strerror’ [-Wimplicit-function-declaration]
    4 |     printf("%s\n", strerror(0));
      |                    ^~~~~~~~
test.c:2:1: note: ‘strerror’ is defined in header ‘<string.h>’; this is probably fixable by adding ‘#include <string.h>’
    1 | #include <stdio.h>
  +++ |+#include <string.h>
    2 |

$ /tmp/gcc-known-headers/bin/g++ test.cpp -o test_cpp
test.cpp: In function ‘int main()’:
test.cpp:4:20: error: ‘strerror’ was not declared in this scope
    4 |     printf("%s\n", strerror(0));
      |                    ^~~~~~~~
test.cpp:2:1: note: ‘strerror’ is defined in header ‘<cstring>’; this is probably fixable by adding ‘#include <cstring>’
    1 | #include <cstdio>
  +++ |+#include <cstring>
    2 |

gcc/c-family/ChangeLog:

	* known-headers.cc (get_stdlib_header_for_name): Add strerror.

gcc/testsuite/ChangeLog:

	* g++.dg/spellcheck-stdlib.C: Add check for strerror.
	* gcc.dg/spellcheck-stdlib-2.c: New test.

Signed-off-by: Oskari Pirhonen <xxc3ncoredxx@gmail.com>
---
v2:
- check for error instead of warning in gcc.dg/spellcheck-stdlib-2.c
- from linaro ci notification email

 gcc/c-family/known-headers.cc              | 1 +
 gcc/testsuite/g++.dg/spellcheck-stdlib.C   | 2 ++
 gcc/testsuite/gcc.dg/spellcheck-stdlib-2.c | 8 ++++++++
 3 files changed, 11 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/spellcheck-stdlib-2.c

Comments

Jason Merrill May 29, 2024, 1:03 p.m. UTC | #1
Pushed, thanks!

On 2/27/24 20:13, Oskari Pirhonen wrote:
> Add proper hints for implicit declaration of strerror.
> 
> The results could be confusing depending on the other included headers.
> These example messages are from compiling a trivial program to print the
> string for an errno value. It only includes stdio.h (cstdio for C++).
> 
> Before:
> $ /tmp/gcc-master/bin/gcc test.c -o test_c
> test.c: In function ‘main’:
> test.c:4:20: warning: implicit declaration of function ‘strerror’; did you mean ‘perror’? [-Wimplicit-function-declaration]
>      4 |     printf("%s\n", strerror(0));
>        |                    ^~~~~~~~
>        |                    perror
> 
> $ /tmp/gcc-master/bin/g++ test.cpp -o test_cpp
> test.cpp: In function ‘int main()’:
> test.cpp:4:20: error: ‘strerror’ was not declared in this scope; did you mean ‘stderr’?
>      4 |     printf("%s\n", strerror(0));
>        |                    ^~~~~~~~
>        |                    stderr
> 
> After:
> $ /tmp/gcc-known-headers/bin/gcc test.c -o test_c
> test.c: In function ‘main’:
> test.c:4:20: warning: implicit declaration of function ‘strerror’ [-Wimplicit-function-declaration]
>      4 |     printf("%s\n", strerror(0));
>        |                    ^~~~~~~~
> test.c:2:1: note: ‘strerror’ is defined in header ‘<string.h>’; this is probably fixable by adding ‘#include <string.h>’
>      1 | #include <stdio.h>
>    +++ |+#include <string.h>
>      2 |
> 
> $ /tmp/gcc-known-headers/bin/g++ test.cpp -o test_cpp
> test.cpp: In function ‘int main()’:
> test.cpp:4:20: error: ‘strerror’ was not declared in this scope
>      4 |     printf("%s\n", strerror(0));
>        |                    ^~~~~~~~
> test.cpp:2:1: note: ‘strerror’ is defined in header ‘<cstring>’; this is probably fixable by adding ‘#include <cstring>’
>      1 | #include <cstdio>
>    +++ |+#include <cstring>
>      2 |
> 
> gcc/c-family/ChangeLog:
> 
> 	* known-headers.cc (get_stdlib_header_for_name): Add strerror.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/spellcheck-stdlib.C: Add check for strerror.
> 	* gcc.dg/spellcheck-stdlib-2.c: New test.
> 
> Signed-off-by: Oskari Pirhonen <xxc3ncoredxx@gmail.com>
> ---
> v2:
> - check for error instead of warning in gcc.dg/spellcheck-stdlib-2.c
> - from linaro ci notification email
> 
>   gcc/c-family/known-headers.cc              | 1 +
>   gcc/testsuite/g++.dg/spellcheck-stdlib.C   | 2 ++
>   gcc/testsuite/gcc.dg/spellcheck-stdlib-2.c | 8 ++++++++
>   3 files changed, 11 insertions(+)
>   create mode 100644 gcc/testsuite/gcc.dg/spellcheck-stdlib-2.c
> 
> diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc
> index dbc42eacde1..871fd714eb5 100644
> --- a/gcc/c-family/known-headers.cc
> +++ b/gcc/c-family/known-headers.cc
> @@ -182,6 +182,7 @@ get_stdlib_header_for_name (const char *name, enum stdlib lib)
>       {"strchr", {"<string.h>", "<cstring>"} },
>       {"strcmp", {"<string.h>", "<cstring>"} },
>       {"strcpy", {"<string.h>", "<cstring>"} },
> +    {"strerror", {"<string.h>", "<cstring>"} },
>       {"strlen", {"<string.h>", "<cstring>"} },
>       {"strncat", {"<string.h>", "<cstring>"} },
>       {"strncmp", {"<string.h>", "<cstring>"} },
> diff --git a/gcc/testsuite/g++.dg/spellcheck-stdlib.C b/gcc/testsuite/g++.dg/spellcheck-stdlib.C
> index fd0f3a9b8c9..33718b8034e 100644
> --- a/gcc/testsuite/g++.dg/spellcheck-stdlib.C
> +++ b/gcc/testsuite/g++.dg/spellcheck-stdlib.C
> @@ -104,6 +104,8 @@ void test_cstring (char *dest, char *src)
>     // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
>     strcpy(dest, "test"); // { dg-error "was not declared" }
>     // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
> +  strerror(0); // { dg-error "was not declared" }
> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
>     strlen("test"); // { dg-error "was not declared" }
>     // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
>     strncat(dest, "test", 3); // { dg-error "was not declared" }
> diff --git a/gcc/testsuite/gcc.dg/spellcheck-stdlib-2.c b/gcc/testsuite/gcc.dg/spellcheck-stdlib-2.c
> new file mode 100644
> index 00000000000..4762e2ddbbd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/spellcheck-stdlib-2.c
> @@ -0,0 +1,8 @@
> +/* { dg-options "-Wimplicit-function-declaration" } */
> +
> +/* Missing <string.h>.  */
> +void test_string_h (void)
> +{
> +  strerror (0); /* { dg-error "implicit declaration of function 'strerror'" } */
> +  /* { dg-message "'strerror' is defined in header '<string.h>'" "" { target *-*-* } .-1 } */
> +}
diff mbox series

Patch

diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc
index dbc42eacde1..871fd714eb5 100644
--- a/gcc/c-family/known-headers.cc
+++ b/gcc/c-family/known-headers.cc
@@ -182,6 +182,7 @@  get_stdlib_header_for_name (const char *name, enum stdlib lib)
     {"strchr", {"<string.h>", "<cstring>"} },
     {"strcmp", {"<string.h>", "<cstring>"} },
     {"strcpy", {"<string.h>", "<cstring>"} },
+    {"strerror", {"<string.h>", "<cstring>"} },
     {"strlen", {"<string.h>", "<cstring>"} },
     {"strncat", {"<string.h>", "<cstring>"} },
     {"strncmp", {"<string.h>", "<cstring>"} },
diff --git a/gcc/testsuite/g++.dg/spellcheck-stdlib.C b/gcc/testsuite/g++.dg/spellcheck-stdlib.C
index fd0f3a9b8c9..33718b8034e 100644
--- a/gcc/testsuite/g++.dg/spellcheck-stdlib.C
+++ b/gcc/testsuite/g++.dg/spellcheck-stdlib.C
@@ -104,6 +104,8 @@  void test_cstring (char *dest, char *src)
   // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
   strcpy(dest, "test"); // { dg-error "was not declared" }
   // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  strerror(0); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
   strlen("test"); // { dg-error "was not declared" }
   // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
   strncat(dest, "test", 3); // { dg-error "was not declared" }
diff --git a/gcc/testsuite/gcc.dg/spellcheck-stdlib-2.c b/gcc/testsuite/gcc.dg/spellcheck-stdlib-2.c
new file mode 100644
index 00000000000..4762e2ddbbd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-stdlib-2.c
@@ -0,0 +1,8 @@ 
+/* { dg-options "-Wimplicit-function-declaration" } */
+
+/* Missing <string.h>.  */
+void test_string_h (void)
+{
+  strerror (0); /* { dg-error "implicit declaration of function 'strerror'" } */
+  /* { dg-message "'strerror' is defined in header '<string.h>'" "" { target *-*-* } .-1 } */
+}