[1/4] More #include suggestions (PR c++/84269)

Message ID 1521762258-50849-2-git-send-email-dmalcolm@redhat.com
State New
Headers show
Series
  • Improvements to #include suggestions
Related show

Commit Message

David Malcolm March 22, 2018, 11:44 p.m.
PR c++/84269 reports a number of names in the C and C++ standard
libraries for which we don't yet offer #include fix-it hints.

This patch adds them (up to comment #9).

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

OK for trunk?

gcc/c-family/ChangeLog:
	PR c++/84269
	* known-headers.cc (get_stdlib_header_for_name): Add various names
	from <assert.h>, <string.h>, and <memory.h>; add more names from
	<stdio.h>.

gcc/cp/ChangeLog:
	PR c++/84269
	* name-lookup.c (get_std_name_hint): Add names from <memory>,
	<tuple>, and <utility>.

gcc/testsuite/ChangeLog:
	PR c++/84269
	* g++.dg/lookup/missing-std-include-6.C: New test.
	* g++.dg/lookup/missing-std-include.C: Add std::pair and
	std::tuple tests.
	* g++.dg/spellcheck-reswords.C: Expect a hint about <cstring>.
	* g++.dg/spellcheck-stdlib.C: Add tests for names in <cstdio>,
	<cstring>, <cassert>, and <cstdlib>.
---
 gcc/c-family/known-headers.cc                      | 33 +++++++++-
 gcc/cp/name-lookup.c                               | 14 +++++
 .../g++.dg/lookup/missing-std-include-6.C          | 62 ++++++++++++++++++
 gcc/testsuite/g++.dg/lookup/missing-std-include.C  |  8 +++
 gcc/testsuite/g++.dg/spellcheck-reswords.C         |  1 +
 gcc/testsuite/g++.dg/spellcheck-stdlib.C           | 73 ++++++++++++++++++++++
 6 files changed, 190 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/lookup/missing-std-include-6.C

-- 
1.8.5.3

Comments

Jason Merrill March 29, 2018, 7:18 p.m. | #1
OK.

On Thu, Mar 22, 2018 at 7:44 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> PR c++/84269 reports a number of names in the C and C++ standard

> libraries for which we don't yet offer #include fix-it hints.

>

> This patch adds them (up to comment #9).

>

> Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

>

> OK for trunk?

>

> gcc/c-family/ChangeLog:

>         PR c++/84269

>         * known-headers.cc (get_stdlib_header_for_name): Add various names

>         from <assert.h>, <string.h>, and <memory.h>; add more names from

>         <stdio.h>.

>

> gcc/cp/ChangeLog:

>         PR c++/84269

>         * name-lookup.c (get_std_name_hint): Add names from <memory>,

>         <tuple>, and <utility>.

>

> gcc/testsuite/ChangeLog:

>         PR c++/84269

>         * g++.dg/lookup/missing-std-include-6.C: New test.

>         * g++.dg/lookup/missing-std-include.C: Add std::pair and

>         std::tuple tests.

>         * g++.dg/spellcheck-reswords.C: Expect a hint about <cstring>.

>         * g++.dg/spellcheck-stdlib.C: Add tests for names in <cstdio>,

>         <cstring>, <cassert>, and <cstdlib>.

> ---

>  gcc/c-family/known-headers.cc                      | 33 +++++++++-

>  gcc/cp/name-lookup.c                               | 14 +++++

>  .../g++.dg/lookup/missing-std-include-6.C          | 62 ++++++++++++++++++

>  gcc/testsuite/g++.dg/lookup/missing-std-include.C  |  8 +++

>  gcc/testsuite/g++.dg/spellcheck-reswords.C         |  1 +

>  gcc/testsuite/g++.dg/spellcheck-stdlib.C           | 73 ++++++++++++++++++++++

>  6 files changed, 190 insertions(+), 1 deletion(-)

>  create mode 100644 gcc/testsuite/g++.dg/lookup/missing-std-include-6.C

>

> diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc

> index ef23cbe..5524d21 100644

> --- a/gcc/c-family/known-headers.cc

> +++ b/gcc/c-family/known-headers.cc

> @@ -57,6 +57,9 @@ get_stdlib_header_for_name (const char *name, enum stdlib lib)

>    gcc_assert (lib < NUM_STDLIBS);

>

>    static const stdlib_hint hints[] = {

> +    /* <assert.h> and <cassert>.  */

> +    {"assert", {"<assert.h>",  "<cassert>"} },

> +

>      /* <errno.h> and <cerrno>.  */

>      {"errno", {"<errno.h>", "<cerrno>"} },

>

> @@ -92,16 +95,44 @@ get_stdlib_header_for_name (const char *name, enum stdlib lib)

>      {"size_t", {"<stddef.h>", "<cstddef>"} },

>      {"wchar_t", {"<stddef.h>", NULL /* a keyword in C++ */} },

>

> -    /* <stdio.h>.  */

> +    /* <stdio.h> and <cstdio>.  */

>      {"BUFSIZ", {"<stdio.h>", "<cstdio>"} },

>      {"EOF", {"<stdio.h>", "<cstdio>"} },

>      {"FILE", {"<stdio.h>", "<cstdio>"} },

>      {"FILENAME_MAX", {"<stdio.h>", "<cstdio>"} },

> +    {"fopen", {"<stdio.h>", "<cstdio>"} },

>      {"fpos_t", {"<stdio.h>", "<cstdio>"} },

> +    {"getchar", {"<stdio.h>", "<cstdio>"} },

> +    {"printf", {"<stdio.h>", "<cstdio>"} },

> +    {"snprintf", {"<stdio.h>", "<cstdio>"} },

> +    {"sprintf", {"<stdio.h>", "<cstdio>"} },

>      {"stderr", {"<stdio.h>", "<cstdio>"} },

>      {"stdin", {"<stdio.h>", "<cstdio>"} },

>      {"stdout", {"<stdio.h>", "<cstdio>"} },

>

> +    /* <stdlib.h> and <cstdlib>.  */

> +    {"free", {"<stdlib.h>", "<cstdlib>"} },

> +    {"malloc", {"<stdlib.h>", "<cstdlib>"} },

> +    {"realloc", {"<stdlib.h>", "<cstdlib>"} },

> +

> +    /* <string.h> and <cstring>.  */

> +    {"memchr", {"<string.h>", "<cstring>"} },

> +    {"memcmp", {"<string.h>", "<cstring>"} },

> +    {"memcpy", {"<string.h>", "<cstring>"} },

> +    {"memmove", {"<string.h>", "<cstring>"} },

> +    {"memset", {"<string.h>", "<cstring>"} },

> +    {"strcat", {"<string.h>", "<cstring>"} },

> +    {"strchr", {"<string.h>", "<cstring>"} },

> +    {"strcmp", {"<string.h>", "<cstring>"} },

> +    {"strcpy", {"<string.h>", "<cstring>"} },

> +    {"strlen", {"<string.h>", "<cstring>"} },

> +    {"strncat", {"<string.h>", "<cstring>"} },

> +    {"strncmp", {"<string.h>", "<cstring>"} },

> +    {"strncpy", {"<string.h>", "<cstring>"} },

> +    {"strrchr", {"<string.h>", "<cstring>"} },

> +    {"strspn", {"<string.h>", "<cstring>"} },

> +    {"strstr", {"<string.h>", "<cstring>"} },

> +

>      /* <stdint.h>.  */

>      {"PTRDIFF_MAX", {"<stdint.h>", "<cstdint>"} },

>      {"PTRDIFF_MIN", {"<stdint.h>", "<cstdint>"} },

> diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c

> index e193b3b..061729a 100644

> --- a/gcc/cp/name-lookup.c

> +++ b/gcc/cp/name-lookup.c

> @@ -5453,6 +5453,12 @@ get_std_name_hint (const char *name)

>      /* <map>.  */

>      {"map", "<map>"},

>      {"multimap", "<map>"},

> +    /* <memory>.  */

> +    {"make_shared", "<memory>"},

> +    {"make_unique", "<memory>"},

> +    {"shared_ptr", "<memory>"},

> +    {"unique_ptr", "<memory>"},

> +    {"weak_ptr", "<memory>"},

>      /* <queue>.  */

>      {"queue", "<queue>"},

>      {"priority_queue", "<queue>"},

> @@ -5472,6 +5478,9 @@ get_std_name_hint (const char *name)

>      {"basic_stringstream", "<sstream>"},

>      /* <stack>.  */

>      {"stack", "<stack>"},

> +    /* <tuple>.  */

> +    {"make_tuple", "<tuple>"},

> +    {"tuple", "<tuple>"},

>      /* <string>.  */

>      {"string", "<string>"},

>      {"wstring", "<string>"},

> @@ -5483,6 +5492,11 @@ get_std_name_hint (const char *name)

>      /* <unordered_set>.  */

>      {"unordered_set", "<unordered_set>"}, // C++11

>      {"unordered_multiset", "<unordered_set>"}, // C++11

> +    /* <utility>.  */

> +    {"forward", "<utility>"},

> +    {"make_pair", "<utility>"},

> +    {"move", "<utility>"},

> +    {"pair", "<utility>"},

>      /* <vector>.  */

>      {"vector", "<vector>"},

>    };

> diff --git a/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C b/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C

> new file mode 100644

> index 0000000..100bcc0

> --- /dev/null

> +++ b/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C

> @@ -0,0 +1,62 @@

> +// { dg-do compile { target c++11 } }

> +

> +/* <memory>.  */

> +

> +template<class T>

> +void test_make_shared ()

> +{

> +  auto p = std::make_shared<T>(); // { dg-error "'make_shared' is not a member of 'std'" }

> +  // { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }

> +  // { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }

> +  // { dg-error "expected primary-expression before '\\)' token" "" { target *-*-* } .-3 }

> +}

> +

> +template<class T>

> +void test_make_unique ()

> +{

> +  auto p = std::make_unique<T>(); // { dg-error "'make_unique' is not a member of 'std'" }

> +  // { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }

> +  // { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }

> +  // { dg-error "expected primary-expression before '\\)' token" "" { target *-*-* } .-3 }

> +}

> +

> +std::shared_ptr<int> test_shared_ptr; // { dg-error "'shared_ptr' in namespace 'std' does not name a template type" }

> +// { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }

> +

> +std::unique_ptr<int> test_unique_ptr; // { dg-error "'unique_ptr' in namespace 'std' does not name a template type" }

> +// { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }

> +

> +std::weak_ptr<int> test_weak_ptr; // { dg-error "'weak_ptr' in namespace 'std' does not name a template type" }

> +// { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }

> +

> +/* <tuple>.  */

> +

> +void test_make_tuple (int i, int j, int k)

> +{

> +  auto t = std::make_tuple (i, j, k); // { dg-error "'make_tuple' is not a member of 'std'" }

> +  // { dg-message "'#include <tuple>'" "" { target *-*-* } .-1 }

> +}

> +

> +/* <utility>.  */

> +

> +template<class T>

> +void test_forward(T&& arg)

> +{

> +  std::forward<T>(arg); // { dg-error "'forward' is not a member of 'std'" }

> +  // { dg-message "'#include <utility>'" "" { target *-*-* } .-1 }

> +  // { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }

> +}

> +

> +void test_make_pair (int i, int j)

> +{

> +  auto p = std::make_pair (i, j); // { dg-error "'make_pair' is not a member of 'std'" }

> +  // { dg-message "'#include <utility>'" "" { target *-*-* } .-1 }

> +}

> +

> +template<class T>

> +void test_move(T&& arg)

> +{

> +  std::move<T>(arg); // { dg-error "'move' is not a member of 'std'" }

> +  // { dg-message "'#include <utility>'" "" { target *-*-* } .-1 }

> +  // { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }

> +}

> diff --git a/gcc/testsuite/g++.dg/lookup/missing-std-include.C b/gcc/testsuite/g++.dg/lookup/missing-std-include.C

> index 82f994f..5452760 100644

> --- a/gcc/testsuite/g++.dg/lookup/missing-std-include.C

> +++ b/gcc/testsuite/g++.dg/lookup/missing-std-include.C

> @@ -26,4 +26,12 @@ void test (void)

>    std::list<int> lst;  // { dg-error ".list. is not a member of .std." }

>    // { dg-message ".std::list. is defined in header .<list>.; did you forget to .#include <list>.?" "" { target *-*-* } .-1 }

>    // { dg-error "expected primary-expression before .int." "" { target *-*-* } .-2 }

> +

> +  std::pair<int,float> p; // { dg-error ".pair. is not a member of .std." }

> +  // { dg-message ".std::pair. is defined in header .<utility>.; did you forget to .#include <utility>.?" "" { target *-*-* } .-1 }

> +  // { dg-error "expected primary-expression before .int." "" { target *-*-* } .-2 }

> +

> +  std::tuple<int,float> p; // { dg-error ".tuple. is not a member of .std." }

> +  // { dg-message ".std::tuple. is defined in header .<tuple>.; did you forget to .#include <tuple>.?" "" { target *-*-* } .-1 }

> +  // { dg-error "expected primary-expression before .int." "" { target *-*-* } .-2 }

>  }

> diff --git a/gcc/testsuite/g++.dg/spellcheck-reswords.C b/gcc/testsuite/g++.dg/spellcheck-reswords.C

> index db6104b..0687666 100644

> --- a/gcc/testsuite/g++.dg/spellcheck-reswords.C

> +++ b/gcc/testsuite/g++.dg/spellcheck-reswords.C

> @@ -8,4 +8,5 @@ void pr80567 (void *p)

>  {

>    memset (p, 0, 4); // { dg-error "not declared" }

>    // { dg-bogus "'else'" "" { target *-*-*} .-1 }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-*} .-2 }

>  }

> diff --git a/gcc/testsuite/g++.dg/spellcheck-stdlib.C b/gcc/testsuite/g++.dg/spellcheck-stdlib.C

> index c7a6626..11a4e3e 100644

> --- a/gcc/testsuite/g++.dg/spellcheck-stdlib.C

> +++ b/gcc/testsuite/g++.dg/spellcheck-stdlib.C

> @@ -35,6 +35,21 @@ void test_cstdio (void)

>

>    EOF; // { dg-error "'EOF' was not declared" }

>    // { dg-message "'EOF' is defined in header '<cstdio>'; did you forget to '#include <cstdio>'?" "" { target *-*-* } .-1 }

> +

> +  fopen ("test.txt"); // { dg-error "'fopen' was not declared" }

> +  // { dg-message "'#include <cstdio>'" "" { target *-*-* } .-1 }

> +

> +  printf ("test\n"); // { dg-error "'printf' was not declared" }

> +  // { dg-message "'#include <cstdio>'" "" { target *-*-* } .-1 }

> +

> +  char tmp[16];

> +  sprintf (tmp, "test\n");  // { dg-error "'sprintf' was not declared" }

> +  // { dg-message "'#include <cstdio>'" "" { target *-*-* } .-1 }

> +  snprintf (tmp, 16, "test\n");  // { dg-error "'snprintf' was not declared" }

> +  // { dg-message "'#include <cstdio>'" "" { target *-*-* } .-1 }

> +

> +  getchar ();  // { dg-error "'getchar' was not declared" }

> +  // { dg-message "'#include <cstdio>'" "" { target *-*-* } .-1 }

>  }

>

>  /* Missing <cerrno>.  */

> @@ -62,6 +77,64 @@ int test_INT_MAX (void)

>    // { dg-message "'INT_MAX' is defined in header '<climits>'; did you forget to '#include <climits>'?" "" { target *-*-* } INT_MAX_line }

>  }

>

> +/* Missing <cstring>.  */

> +

> +void test_cstring (char *dest, char *src)

> +{

> +  memchr(dest, 'a', 4); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  memcmp(dest, src, 4); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  memcpy(dest, src, 4); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  memmove(dest, src, 4); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  memset(dest, 'a', 4); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  strcat(dest, "test"); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  strchr("test", 'e'); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  strcmp(dest, "test"); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  strcpy(dest, "test"); // { 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" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  strncmp(dest, "test", 3); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  strncpy(dest, "test", 3); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  strrchr("test", 'e'); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  strspn(dest, "test"); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +  strstr(dest, "test"); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }

> +}

> +

> +/* Missing <cassert>.  */

> +

> +void test_cassert (int a, int b)

> +{

> +  assert (a == b); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cassert>'" "" { target *-*-* } .-1 }

> +}

> +

> +/* Missing <cstdlib>.  */

> +

> +void test_cstdlib (void *q)

> +{

> +  void *ptr = malloc (64); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstdlib>'" "" { target *-*-* } .-1 }

> +  free (ptr); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstdlib>'" "" { target *-*-* } .-1 }

> +  q = realloc (q, 1024); // { dg-error "was not declared" }

> +  // { dg-message "'#include <cstdlib>'" "" { target *-*-* } .-1 }

> +}

> +

>  /* Verify that we don't offer suggestions to stdlib globals names when

>     there's an explicit namespace.  */

>

> --

> 1.8.5.3

>

Patch

diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc
index ef23cbe..5524d21 100644
--- a/gcc/c-family/known-headers.cc
+++ b/gcc/c-family/known-headers.cc
@@ -57,6 +57,9 @@  get_stdlib_header_for_name (const char *name, enum stdlib lib)
   gcc_assert (lib < NUM_STDLIBS);
 
   static const stdlib_hint hints[] = {
+    /* <assert.h> and <cassert>.  */
+    {"assert", {"<assert.h>",  "<cassert>"} },
+
     /* <errno.h> and <cerrno>.  */
     {"errno", {"<errno.h>", "<cerrno>"} },
 
@@ -92,16 +95,44 @@  get_stdlib_header_for_name (const char *name, enum stdlib lib)
     {"size_t", {"<stddef.h>", "<cstddef>"} },
     {"wchar_t", {"<stddef.h>", NULL /* a keyword in C++ */} },
 
-    /* <stdio.h>.  */
+    /* <stdio.h> and <cstdio>.  */
     {"BUFSIZ", {"<stdio.h>", "<cstdio>"} },
     {"EOF", {"<stdio.h>", "<cstdio>"} },
     {"FILE", {"<stdio.h>", "<cstdio>"} },
     {"FILENAME_MAX", {"<stdio.h>", "<cstdio>"} },
+    {"fopen", {"<stdio.h>", "<cstdio>"} },
     {"fpos_t", {"<stdio.h>", "<cstdio>"} },
+    {"getchar", {"<stdio.h>", "<cstdio>"} },
+    {"printf", {"<stdio.h>", "<cstdio>"} },
+    {"snprintf", {"<stdio.h>", "<cstdio>"} },
+    {"sprintf", {"<stdio.h>", "<cstdio>"} },
     {"stderr", {"<stdio.h>", "<cstdio>"} },
     {"stdin", {"<stdio.h>", "<cstdio>"} },
     {"stdout", {"<stdio.h>", "<cstdio>"} },
 
+    /* <stdlib.h> and <cstdlib>.  */
+    {"free", {"<stdlib.h>", "<cstdlib>"} },
+    {"malloc", {"<stdlib.h>", "<cstdlib>"} },
+    {"realloc", {"<stdlib.h>", "<cstdlib>"} },
+
+    /* <string.h> and <cstring>.  */
+    {"memchr", {"<string.h>", "<cstring>"} },
+    {"memcmp", {"<string.h>", "<cstring>"} },
+    {"memcpy", {"<string.h>", "<cstring>"} },
+    {"memmove", {"<string.h>", "<cstring>"} },
+    {"memset", {"<string.h>", "<cstring>"} },
+    {"strcat", {"<string.h>", "<cstring>"} },
+    {"strchr", {"<string.h>", "<cstring>"} },
+    {"strcmp", {"<string.h>", "<cstring>"} },
+    {"strcpy", {"<string.h>", "<cstring>"} },
+    {"strlen", {"<string.h>", "<cstring>"} },
+    {"strncat", {"<string.h>", "<cstring>"} },
+    {"strncmp", {"<string.h>", "<cstring>"} },
+    {"strncpy", {"<string.h>", "<cstring>"} },
+    {"strrchr", {"<string.h>", "<cstring>"} },
+    {"strspn", {"<string.h>", "<cstring>"} },
+    {"strstr", {"<string.h>", "<cstring>"} },
+
     /* <stdint.h>.  */
     {"PTRDIFF_MAX", {"<stdint.h>", "<cstdint>"} },
     {"PTRDIFF_MIN", {"<stdint.h>", "<cstdint>"} },
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e193b3b..061729a 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -5453,6 +5453,12 @@  get_std_name_hint (const char *name)
     /* <map>.  */
     {"map", "<map>"},
     {"multimap", "<map>"},
+    /* <memory>.  */
+    {"make_shared", "<memory>"},
+    {"make_unique", "<memory>"},
+    {"shared_ptr", "<memory>"},
+    {"unique_ptr", "<memory>"},
+    {"weak_ptr", "<memory>"},
     /* <queue>.  */
     {"queue", "<queue>"},
     {"priority_queue", "<queue>"},
@@ -5472,6 +5478,9 @@  get_std_name_hint (const char *name)
     {"basic_stringstream", "<sstream>"},
     /* <stack>.  */
     {"stack", "<stack>"},
+    /* <tuple>.  */
+    {"make_tuple", "<tuple>"},
+    {"tuple", "<tuple>"},
     /* <string>.  */
     {"string", "<string>"},
     {"wstring", "<string>"},
@@ -5483,6 +5492,11 @@  get_std_name_hint (const char *name)
     /* <unordered_set>.  */
     {"unordered_set", "<unordered_set>"}, // C++11
     {"unordered_multiset", "<unordered_set>"}, // C++11
+    /* <utility>.  */
+    {"forward", "<utility>"},
+    {"make_pair", "<utility>"},
+    {"move", "<utility>"},
+    {"pair", "<utility>"},
     /* <vector>.  */
     {"vector", "<vector>"},
   };
diff --git a/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C b/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C
new file mode 100644
index 0000000..100bcc0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C
@@ -0,0 +1,62 @@ 
+// { dg-do compile { target c++11 } }
+
+/* <memory>.  */
+
+template<class T>
+void test_make_shared ()
+{
+  auto p = std::make_shared<T>(); // { dg-error "'make_shared' is not a member of 'std'" }
+  // { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }
+  // { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }
+  // { dg-error "expected primary-expression before '\\)' token" "" { target *-*-* } .-3 }
+}
+
+template<class T>
+void test_make_unique ()
+{
+  auto p = std::make_unique<T>(); // { dg-error "'make_unique' is not a member of 'std'" }
+  // { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }
+  // { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }
+  // { dg-error "expected primary-expression before '\\)' token" "" { target *-*-* } .-3 }
+}
+
+std::shared_ptr<int> test_shared_ptr; // { dg-error "'shared_ptr' in namespace 'std' does not name a template type" }
+// { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }
+
+std::unique_ptr<int> test_unique_ptr; // { dg-error "'unique_ptr' in namespace 'std' does not name a template type" }
+// { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }
+
+std::weak_ptr<int> test_weak_ptr; // { dg-error "'weak_ptr' in namespace 'std' does not name a template type" }
+// { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }
+
+/* <tuple>.  */
+
+void test_make_tuple (int i, int j, int k)
+{
+  auto t = std::make_tuple (i, j, k); // { dg-error "'make_tuple' is not a member of 'std'" }
+  // { dg-message "'#include <tuple>'" "" { target *-*-* } .-1 }
+}
+
+/* <utility>.  */
+
+template<class T>
+void test_forward(T&& arg) 
+{
+  std::forward<T>(arg); // { dg-error "'forward' is not a member of 'std'" }
+  // { dg-message "'#include <utility>'" "" { target *-*-* } .-1 }
+  // { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }
+}
+
+void test_make_pair (int i, int j)
+{
+  auto p = std::make_pair (i, j); // { dg-error "'make_pair' is not a member of 'std'" }
+  // { dg-message "'#include <utility>'" "" { target *-*-* } .-1 }
+}
+
+template<class T>
+void test_move(T&& arg) 
+{
+  std::move<T>(arg); // { dg-error "'move' is not a member of 'std'" }
+  // { dg-message "'#include <utility>'" "" { target *-*-* } .-1 }
+  // { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/g++.dg/lookup/missing-std-include.C b/gcc/testsuite/g++.dg/lookup/missing-std-include.C
index 82f994f..5452760 100644
--- a/gcc/testsuite/g++.dg/lookup/missing-std-include.C
+++ b/gcc/testsuite/g++.dg/lookup/missing-std-include.C
@@ -26,4 +26,12 @@  void test (void)
   std::list<int> lst;  // { dg-error ".list. is not a member of .std." }
   // { dg-message ".std::list. is defined in header .<list>.; did you forget to .#include <list>.?" "" { target *-*-* } .-1 }
   // { dg-error "expected primary-expression before .int." "" { target *-*-* } .-2 }
+
+  std::pair<int,float> p; // { dg-error ".pair. is not a member of .std." }
+  // { dg-message ".std::pair. is defined in header .<utility>.; did you forget to .#include <utility>.?" "" { target *-*-* } .-1 }
+  // { dg-error "expected primary-expression before .int." "" { target *-*-* } .-2 }
+
+  std::tuple<int,float> p; // { dg-error ".tuple. is not a member of .std." }
+  // { dg-message ".std::tuple. is defined in header .<tuple>.; did you forget to .#include <tuple>.?" "" { target *-*-* } .-1 }
+  // { dg-error "expected primary-expression before .int." "" { target *-*-* } .-2 }
 }
diff --git a/gcc/testsuite/g++.dg/spellcheck-reswords.C b/gcc/testsuite/g++.dg/spellcheck-reswords.C
index db6104b..0687666 100644
--- a/gcc/testsuite/g++.dg/spellcheck-reswords.C
+++ b/gcc/testsuite/g++.dg/spellcheck-reswords.C
@@ -8,4 +8,5 @@  void pr80567 (void *p)
 {
   memset (p, 0, 4); // { dg-error "not declared" }
   // { dg-bogus "'else'" "" { target *-*-*} .-1 }
+  // { dg-message "'#include <cstring>'" "" { target *-*-*} .-2 }
 }
diff --git a/gcc/testsuite/g++.dg/spellcheck-stdlib.C b/gcc/testsuite/g++.dg/spellcheck-stdlib.C
index c7a6626..11a4e3e 100644
--- a/gcc/testsuite/g++.dg/spellcheck-stdlib.C
+++ b/gcc/testsuite/g++.dg/spellcheck-stdlib.C
@@ -35,6 +35,21 @@  void test_cstdio (void)
 
   EOF; // { dg-error "'EOF' was not declared" }
   // { dg-message "'EOF' is defined in header '<cstdio>'; did you forget to '#include <cstdio>'?" "" { target *-*-* } .-1 }
+
+  fopen ("test.txt"); // { dg-error "'fopen' was not declared" }
+  // { dg-message "'#include <cstdio>'" "" { target *-*-* } .-1 }
+
+  printf ("test\n"); // { dg-error "'printf' was not declared" }
+  // { dg-message "'#include <cstdio>'" "" { target *-*-* } .-1 }
+  
+  char tmp[16];
+  sprintf (tmp, "test\n");  // { dg-error "'sprintf' was not declared" }
+  // { dg-message "'#include <cstdio>'" "" { target *-*-* } .-1 }
+  snprintf (tmp, 16, "test\n");  // { dg-error "'snprintf' was not declared" }
+  // { dg-message "'#include <cstdio>'" "" { target *-*-* } .-1 }
+
+  getchar ();  // { dg-error "'getchar' was not declared" }
+  // { dg-message "'#include <cstdio>'" "" { target *-*-* } .-1 }
 }
 
 /* Missing <cerrno>.  */
@@ -62,6 +77,64 @@  int test_INT_MAX (void)
   // { dg-message "'INT_MAX' is defined in header '<climits>'; did you forget to '#include <climits>'?" "" { target *-*-* } INT_MAX_line }
 }
 
+/* Missing <cstring>.  */
+
+void test_cstring (char *dest, char *src)
+{
+  memchr(dest, 'a', 4); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  memcmp(dest, src, 4); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  memcpy(dest, src, 4); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  memmove(dest, src, 4); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  memset(dest, 'a', 4); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  strcat(dest, "test"); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  strchr("test", 'e'); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  strcmp(dest, "test"); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  strcpy(dest, "test"); // { 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" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  strncmp(dest, "test", 3); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  strncpy(dest, "test", 3); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  strrchr("test", 'e'); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  strspn(dest, "test"); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+  strstr(dest, "test"); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstring>'" "" { target *-*-* } .-1 }
+}
+
+/* Missing <cassert>.  */
+
+void test_cassert (int a, int b)
+{
+  assert (a == b); // { dg-error "was not declared" }
+  // { dg-message "'#include <cassert>'" "" { target *-*-* } .-1 }
+}
+
+/* Missing <cstdlib>.  */
+
+void test_cstdlib (void *q)
+{
+  void *ptr = malloc (64); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstdlib>'" "" { target *-*-* } .-1 }
+  free (ptr); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstdlib>'" "" { target *-*-* } .-1 }
+  q = realloc (q, 1024); // { dg-error "was not declared" }
+  // { dg-message "'#include <cstdlib>'" "" { target *-*-* } .-1 }
+}
+
 /* Verify that we don't offer suggestions to stdlib globals names when
    there's an explicit namespace.  */