Bug 84269 - More suggestions for missing #include
Summary: More suggestions for missing #include
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.0
: P5 normal
Target Milestone: 8.0
Assignee: David Malcolm
URL:
Keywords: diagnostic, patch
: 84896 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-02-07 18:07 UTC by David Malcolm
Modified: 2023-10-03 22:44 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-02-07 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Malcolm 2018-02-07 18:07:42 UTC
As noted in the fix for PR c++/81610 and PR c++/80567 here:
  https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02200.html

> The C++ FE is missing a suggestion about which #include to use for
> "memset", but I'd prefer to treat that as a follow-up patch (and
> probably for next stage 1).

I've filing this PR to capture that (for gcc 9 stage 1).

See those PRs for more info.
Comment 1 David Malcolm 2018-02-13 16:11:09 UTC
Another one: presumably we should suggest <utility> when "std::move" isn't recognized (though maybe we need some smarts to deal with pre C++11 here)
Comment 2 David Malcolm 2018-02-14 20:20:08 UTC
Another one: std::make_tuple

...and so on.
Comment 3 David Malcolm 2018-03-16 22:14:08 UTC
Another one:

void test (char *dst, const char *src)
{
    strncpy (dst, 10, src);
}

In function 'void test(char*, const char*)':
<source>:3:5: error: 'strncpy' was not declared in this scope
     strncpy (dst, 10, src);
     ^~~~~~~
<source>:3:5: note: suggested alternative: 'struct'
     strncpy (dst, 10, src);
     ^~~~~~~
     struct
Comment 4 David Malcolm 2018-03-17 23:05:54 UTC
And another, as reported at https://www.reddit.com/r/cpp/comments/84op5c/usability_improvements_in_gcc_8/dvtl76x/

> const auto s = strlen("test");
> with gcc (trunk) gives the following error:
> [x86-64 gcc (trunk) #1] error: 'strlen' was not declared in this scope
> [x86-64 gcc (trunk) #1] note: suggested alternative: 'struct'

Many of these likely apply to the C frontend as well.
Comment 5 David Malcolm 2018-03-17 23:11:20 UTC
(In reply to David Malcolm from comment #4)
> And another, as reported at
> https://www.reddit.com/r/cpp/comments/84op5c/usability_improvements_in_gcc_8/
> dvtl76x/
> 
> > const auto s = strlen("test");
> > with gcc (trunk) gives the following error:
> > [x86-64 gcc (trunk) #1] error: 'strlen' was not declared in this scope
> > [x86-64 gcc (trunk) #1] note: suggested alternative: 'struct'

Confirmed (with r258277).  We definitely shouldn't suggest "struct" here, which feels reminiscent of PR c++/81610 and PR c++/80567, but which appears to still be unfixed.
Comment 6 David Malcolm 2018-03-21 15:10:48 UTC
Another one, affecting C++ only:

void f() {
    printf("test");
}

<source>: In function 'void f()':
<source>:2:5: error: 'printf' was not declared in this scope
     printf("test");
     ^~~~~~
<source>:2:5: note: suggested alternative: 'int'
     printf("test");
     ^~~~~~
     int
Comment 7 David Malcolm 2018-03-21 23:13:05 UTC
Another one, from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82967#c1

#include <math.h>

void test (float pf, float inff)
{
  assert (pf == inff);
}


<source>: In function 'test':
<source>:5:3: warning: implicit declaration of function 'assert'; did you mean 'sqrt'? [-Wimplicit-function-declaration]
   assert (pf == inff);
   ^~~~~~
   sqrt

We should suggest including <assert.h> for this.
Comment 8 David Malcolm 2018-03-22 13:42:14 UTC
From PR 84896:

gcc 8 currently emits the following for:

  std::pair<int, int> foo;

error: 'pair' in namespace 'std' does not name a template type
 std::pair<int, int> foo;
      ^~~~

We ought to suggest including <utility> for this, and probably various other stdlib templates.
Comment 9 David Malcolm 2018-03-22 13:42:49 UTC
*** Bug 84896 has been marked as a duplicate of this bug. ***
Comment 10 Jonathan Wakely 2018-03-22 15:53:04 UTC
(In reply to David Malcolm from comment #8)
> We ought to suggest including <utility> for this, and probably various other
> stdlib templates.

This should cover most of the common ones:

<istream> std::istream
<ostream> std::ostream
<fstream> std::fstream, std::ofstream, std::ifstream
<sstream> std::stringstream, std::istringstream, std::ostringstream
<string> std::string, std::basic_string
<utility> std::pair, std::make_pair
<list> std::list
<deque> std::deque
<vector> std::vector
<map> std::map, std::multimap
<set> std::set, std::multiset
<stack> std::stack
<queue> std::queue, std::priority_queue
<complex> std::complex
<bitset> std::bitset
<iterator> std::iterator_traits, std::distance, std::advance,
           std::reverse_iterator, std::back_inserter, std::front_inserter,
           std::inserter, std::ostream_iterator, std::istream_iterator,
           std::ostreambuf_iterator, std::istreambuf_iterator

Since C++11:
<array> std::array
<forward_list> std::forward_list
<functional> std::hash, std::mem_fn, std::bind, std::function
<memory> std::unique_ptr, std::shared_ptr
<tuple> std::tuple, std::tuple_size, std::tuple_element
<utility> std::forward, std::move, std::declval
<unordered_map> std::unordered_map, std::unordered_multimap
<unordered_set> std::unordered_set, std::unordered_multiset
<mutex> std::mutex, std::timed_mutex, std::recursive_mutex,
        std::recursive_timed_mutex, std::once_flag, std::call_once, 
        std::lock, std::try_lock, std::lock_guard, std::unique_lock
<condition_variable> std::condition_variable, std::condition_variable_any
<thread> std::thread
<atomic> std::atomic, std::atomic_flag
<future> std::future, std::promise, std::packaged_task, std::async
<iterator> std::next, std::prev, std::move_iterator, std::begin, std::end

Since C++14:
<shared_mutex> std::shared_timed_mutex

Since C++17:
<string_view> std::string_view
<any> std::any, std::any_cast, std::make_any
<optional> std::optional, std::make_optional
<variant> std::variant, std::visit
<mutex> std::scoped_lock
<shared_mutex> std::shared_mutex
Comment 12 David Malcolm 2018-03-29 20:44:20 UTC
Author: dmalcolm
Date: Thu Mar 29 20:43:48 2018
New Revision: 258966

URL: https://gcc.gnu.org/viewcvs?rev=258966&root=gcc&view=rev
Log:
More #include suggestions (PR c++/84269)

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


Added:
    trunk/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C
Modified:
    trunk/gcc/c-family/ChangeLog
    trunk/gcc/c-family/known-headers.cc
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/name-lookup.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/lookup/missing-std-include.C
    trunk/gcc/testsuite/g++.dg/spellcheck-reswords.C
    trunk/gcc/testsuite/g++.dg/spellcheck-stdlib.C
Comment 13 David Malcolm 2018-04-06 17:37:05 UTC
Author: dmalcolm
Date: Fri Apr  6 17:36:33 2018
New Revision: 259184

URL: https://gcc.gnu.org/viewcvs?rev=259184&root=gcc&view=rev
Log:
C++: more std header hints; filter on C++ dialect (PR c++/84269)

This patch adds more suggestions as per:
  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84269#c10
some of which need C++14 and C++17, and some of which use headers that
exist in earlier standards.

For example, <memory> exists in C++98, but if the user attempts to
use std::make_shared with -std=c++98, they are suggested to include
<memory>, even if they've already included it.

This patch adds the missing names, and fixes the nonsensical suggestions
by detecting if the name isn't available yet, based on the user's
dialect, and reporting things more intelligently:

t.cc: In function 'void test_make_shared()':
t.cc:5:8: error: 'make_shared' is not a member of 'std'
   std::make_shared<int>();
        ^~~~~~~~~~~
t.cc:5:8: note: 'std::make_shared' is only available from C++11 onwards

gcc/cp/ChangeLog:
	PR c++/84269
	* name-lookup.c (struct std_name_hint): Move out of
	get_std_name_hint; add field "min_dialect".
	(get_std_name_hint): Add min_dialect values to all initializers.
	Add <any>, <atomic>, <bitset>, <condition_variable>, <functional>,
	<future>, <istream>, <iterator>, <ostream>, <mutex>, <optional>,
	<shared_mutex>, <string_view>, <thread>, and <variant>.
	Add fstream, ifstream, and ofstream to <fstream>.
	Add istringstream, ostringstream, and stringstream to <sstream>.
	Add basic_string to <string>.
	Add tuple_element and tuple_size to <tuple>.
	Add declval to <utility>.
	Fix ordering of <queue> and <tuple>.
	Return a std_name_hint, rather than a const char *.
	(get_cxx_dialect_name): New function.
	(maybe_suggest_missing_std_header): Detect names that aren't yet
	available in the current dialect, and instead of suggesting a
	missing #include, warn about the dialect.

gcc/testsuite/ChangeLog:
	PR c++/84269
	* g++.dg/lookup/missing-std-include-6.C: Move std::array and
	std::tuple here since they need C++11.
	* g++.dg/lookup/missing-std-include-8.C: New test.
	* g++.dg/lookup/missing-std-include.C: Move std::array and
	std::tuple test to missing-std-include-6.C to avoid failures
	with C++98.


Added:
    trunk/gcc/testsuite/g++.dg/lookup/missing-std-include-8.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/name-lookup.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C
    trunk/gcc/testsuite/g++.dg/lookup/missing-std-include.C
Comment 14 David Malcolm 2018-04-06 17:40:34 UTC
r259184 should cover everything so far; closing this one out.