c++: handle misspelled concepts and missing #include <concepts>
gcc/cp/ChangeLog: * name-lookup.cc (suggest_alternative_in_explicit_scope): Gracefully handle non-namespaces, such as scoped enums. * parser.cc (cp_parser_name_lookup_error): Provide a name_hint for the case where we're in an explicit scope. * std-name-hint.gperf: Add <concepts>. * std-name-hint.h: Regenerate. gcc/testsuite/ChangeLog: * g++.dg/concepts/missing-header.C: New test. * g++.dg/concepts/misspelled-concept.C: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
4f5b7f1b73
commit
31c08879dc
6 changed files with 1316 additions and 1131 deletions
|
@ -7351,6 +7351,9 @@ suggest_alternative_in_explicit_scope (location_t location, tree name,
|
|||
if (name == error_mark_node)
|
||||
return name_hint ();
|
||||
|
||||
if (TREE_CODE (scope) != NAMESPACE_DECL)
|
||||
return name_hint ();
|
||||
|
||||
/* Resolve any namespace aliases. */
|
||||
scope = ORIGINAL_NAMESPACE (scope);
|
||||
|
||||
|
|
|
@ -3387,8 +3387,25 @@ cp_parser_name_lookup_error (cp_parser* parser,
|
|||
if (decl == error_mark_node)
|
||||
{
|
||||
if (parser->scope && parser->scope != global_namespace)
|
||||
error_at (location, "%<%E::%E%> has not been declared",
|
||||
parser->scope, name);
|
||||
{
|
||||
auto_diagnostic_group sentinel;
|
||||
name_hint hint
|
||||
= suggest_alternative_in_explicit_scope (location, name,
|
||||
parser->scope);;
|
||||
if (const char *suggestion = hint.suggestion ())
|
||||
{
|
||||
/* Ideally we'd have a fix-it hint here, but LOCATION
|
||||
isn't necessarily that of the name. */
|
||||
error_at (location,
|
||||
"%<%E::%E%> has not been declared;"
|
||||
" did you mean %<%E::%s%>?",
|
||||
parser->scope, name,
|
||||
parser->scope, suggestion);
|
||||
}
|
||||
else
|
||||
error_at (location, "%<%E::%E%> has not been declared",
|
||||
parser->scope, name);
|
||||
}
|
||||
else if (parser->scope == global_namespace)
|
||||
error_at (location, "%<::%E%> has not been declared", name);
|
||||
else if (parser->object_scope
|
||||
|
|
|
@ -102,6 +102,39 @@ weak_ordering, "<compare>", cxx20
|
|||
# <complex>
|
||||
complex, "<complex>", cxx98
|
||||
complex_literals, "<complex>", cxx14
|
||||
# <concepts>
|
||||
same_as, "<concepts>", cxx20
|
||||
derived_from, "<concepts>", cxx20
|
||||
convertible_to, "<concepts>", cxx20
|
||||
common_reference_with, "<concepts>", cxx20
|
||||
common_with, "<concepts>", cxx20
|
||||
integral, "<concepts>", cxx20
|
||||
signed_integral, "<concepts>", cxx20
|
||||
unsigned_integral, "<concepts>", cxx20
|
||||
floating_point, "<concepts>", cxx20
|
||||
assignable_from, "<concepts>", cxx20
|
||||
swappable, "<concepts>", cxx20
|
||||
swappable_with, "<concepts>", cxx20
|
||||
destructible, "<concepts>", cxx20
|
||||
constructible_from, "<concepts>", cxx20
|
||||
default_initializable, "<concepts>", cxx20
|
||||
move_constructible, "<concepts>", cxx20
|
||||
copy_constructible, "<concepts>", cxx20
|
||||
equality_comparable, "<concepts>", cxx20
|
||||
equality_comparable_with, "<concepts>", cxx20
|
||||
totally_ordered, "<concepts>", cxx20
|
||||
totally_ordered_with, "<concepts>", cxx20
|
||||
movable, "<concepts>", cxx20
|
||||
copyable, "<concepts>", cxx20
|
||||
semiregular, "<concepts>", cxx20
|
||||
regular, "<concepts>", cxx20
|
||||
invocable, "<concepts>", cxx20
|
||||
regular_invocable, "<concepts>", cxx20
|
||||
predicate, "<concepts>", cxx20
|
||||
relation, "<concepts>", cxx20
|
||||
equivalence_relation, "<concepts>", cxx20
|
||||
strict_weak_order, "<concepts>", cxx20
|
||||
ranges::swap, "<concepts>", cxx20
|
||||
# <condition_variable>
|
||||
condition_variable, "<condition_variable>", cxx11
|
||||
condition_variable_any, "<condition_variable>", cxx11
|
||||
|
|
File diff suppressed because it is too large
Load diff
6
gcc/testsuite/g++.dg/concepts/missing-header.C
Normal file
6
gcc/testsuite/g++.dg/concepts/missing-header.C
Normal file
|
@ -0,0 +1,6 @@
|
|||
// { dg-do compile { target c++20 } }
|
||||
// { dg-options "-fconcepts" }
|
||||
|
||||
template <std::integral N> foo (N); // { dg-error "'std::integral' has not been declared" }
|
||||
// { dg-message "'std::integral' is defined in header '<concepts>'" "note" { target *-*-* } .-1 }
|
||||
// { dg-error "expected" "followup" { target *-*-* } .-2 }
|
7
gcc/testsuite/g++.dg/concepts/misspelled-concept.C
Normal file
7
gcc/testsuite/g++.dg/concepts/misspelled-concept.C
Normal file
|
@ -0,0 +1,7 @@
|
|||
// { dg-do compile { target c++20 } }
|
||||
// { dg-options "-fconcepts" }
|
||||
|
||||
#include <concepts>
|
||||
|
||||
template <std::unsinged_integral N> foo (N); // { dg-error "'std::unsinged_integral' has not been declared; did you mean 'std::unsigned_integral'" }
|
||||
// { dg-error "expected" "followup" { target *-*-* } .-1 }
|
Loading…
Add table
Reference in a new issue