Commit e1c7971b by David Malcolm Committed by David Malcolm

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.

From-SVN: r259184
parent c617fb56
2018-04-06 David Malcolm <dmalcolm@redhat.com>
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.
2018-04-06 Jakub Jelinek <jakub@redhat.com>
PR c++/85210
......
2018-04-06 David Malcolm <dmalcolm@redhat.com>
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.
2018-04-06 Jakub Jelinek <jakub@redhat.com>
PR debug/85252
......
......@@ -60,3 +60,16 @@ void test_move(T&& arg)
// { dg-message "'#include <utility>'" "" { target *-*-* } .-1 }
// { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }
}
void test_array ()
{
std::array a; // { dg-error ".array. is not a member of .std." }
// { dg-message ".std::array. is defined in header .<array>.; did you forget to .#include <array>.?" "" { target *-*-* } .-1 }
}
void test_tuple ()
{
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 }
}
/* Verify that we don't offer #include suggestions for things that
aren't yet available due to the C++ dialect in use. */
// { dg-do compile { target c++98_only } }
#include <memory>
template<class T>
void test_make_shared ()
{
std::make_shared<T>(); // { dg-error "'make_shared' is not a member of 'std'" }
// { dg-message "'std::make_shared' is only available from C\\+\\+11 onwards" "" { target *-*-* } .-1 }
// { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }
// { dg-error "expected primary-expression before '\\)' token" "" { target *-*-* } .-3 }
}
void test_array ()
{
std::array a; // { dg-error "'array' is not a member of 'std'" }
// { dg-message "'std::array' is only available from C\\+\\+11 onwards" "" { target *-*-* } .-1 }
}
void test_tuple ()
{
std::tuple<int,float> p; // { dg-error "'tuple' is not a member of 'std'" }
// { dg-message "'std::tuple' is only available from C\\+\\+11 onwards" "" { target *-*-* } .-1 }
// { dg-error "expected primary-expression before 'int'" "" { target *-*-* } .-2 }
}
/* Since C++14. */
std::shared_timed_mutex m; // { dg-error "'shared_timed_mutex' in namespace 'std' does not name a type" }
// { dg-message "'std::shared_timed_mutex' is only available from C\\+\\+14 onwards" "" { target *-*-* } .-1 }
/* Since C++17: */
std::string_view sv; // { dg-error "'string_view' in namespace 'std' does not name a type" }
// { dg-message "'std::string_view' is only available from C\\+\\+17 onwards" "" { target *-*-* } .-1 }
/* Verify interaction with "using namespace std;". */
using namespace std;
void test_via_using_directive ()
{
shared_ptr<int> p; // { dg-error "'shared_ptr' was not declared in this scope" }
// { dg-message "'std::shared_ptr' is only available from C\\+\\+11 onwards" "" { target *-*-* } .-1 }
// { dg-error "expected primary-expression before 'int'" "" { target *-*-* } .-2 }
}
......@@ -13,9 +13,6 @@ void test (void)
std::cin >> i; // { dg-error ".cin. is not a member of .std." }
// { dg-message ".std::cin. is defined in header .<iostream>.; did you forget to .#include <iostream>.?" "" { target *-*-* } .-1 }
std::array a; // { dg-error ".array. is not a member of .std." }
// { dg-message ".std::array. is defined in header .<array>.; did you forget to .#include <array>.?" "" { target *-*-* } .-1 }
std::deque a; // { dg-error ".deque. is not a member of .std." }
// { dg-message ".std::deque. is defined in header .<deque>.; did you forget to .#include <deque>.?" "" { target *-*-* } .-1 }
......@@ -30,8 +27,4 @@ void test (void)
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 }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment