Skip to content

Commit

Permalink
More #include suggestions (PR c++/84269)
Browse files Browse the repository at this point in the history
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).

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>.



git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@258966 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
dmalcolm committed Mar 29, 2018
1 parent 9830757 commit 5760796
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 1 deletion.
7 changes: 7 additions & 0 deletions gcc/c-family/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
2018-03-29 David Malcolm <[email protected]>

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>.

2018-03-27 Jakub Jelinek <[email protected]>

PR c++/85061
Expand Down
33 changes: 32 additions & 1 deletion gcc/c-family/known-headers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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>"} },

Expand Down Expand Up @@ -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>"} },
Expand Down
6 changes: 6 additions & 0 deletions gcc/cp/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2018-03-29 David Malcolm <[email protected]>

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

2018-03-29 Jason Merrill <[email protected]>

PR c++/85093 - too many template args with pack expansion.
Expand Down
14 changes: 14 additions & 0 deletions gcc/cp/name-lookup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>"},
Expand All @@ -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>"},
Expand All @@ -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>"},
};
Expand Down
10 changes: 10 additions & 0 deletions gcc/testsuite/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
2018-03-29 David Malcolm <[email protected]>

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>.

2018-03-29 Vladimir Makarov <[email protected]>

PR inline-asm/84985
Expand Down
62 changes: 62 additions & 0 deletions gcc/testsuite/g++.dg/lookup/missing-std-include-6.C
Original file line number Diff line number Diff line change
@@ -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 }
}
8 changes: 8 additions & 0 deletions gcc/testsuite/g++.dg/lookup/missing-std-include.C
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}
1 change: 1 addition & 0 deletions gcc/testsuite/g++.dg/spellcheck-reswords.C
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}
73 changes: 73 additions & 0 deletions gcc/testsuite/g++.dg/spellcheck-stdlib.C
Original file line number Diff line number Diff line change
Expand Up @@ -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>. */
Expand Down Expand Up @@ -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. */

Expand Down

0 comments on commit 5760796

Please sign in to comment.