C++: namespaces and scopes for enum values (PR c++/88121)
Consider this test case: namespace json { enum { JSON_OBJECT }; } void test () { JSON_OBJECT; } which erroneously accesses an enum value in another namespace without qualifying the access. GCC 6 through 8 issue a suggestion that doesn't mention the namespace: <source>: In function 'void test()': <source>:8:3: error: 'JSON_OBJECT' was not declared in this scope JSON_OBJECT; ^~~~~~~~~~~ <source>:8:3: note: suggested alternative: <source>:3:10: note: 'JSON_OBJECT' enum { JSON_OBJECT }; ^~~~~~~~~~~ which is suboptimal. I made the problem worse with r265610, which consolidates the single suggestion into the error, and emits: <source>: In function 'void test()': <source>:8:3: error: 'JSON_OBJECT' was not declared in this scope; did you mean 'JSON_OBJECT'? 8 | JSON_OBJECT; | ^~~~~~~~~~~ | JSON_OBJECT <source>:3:10: note: 'JSON_OBJECT' declared here 3 | enum { JSON_OBJECT }; | ^~~~~~~~~~~ where the message: 'JSON_OBJECT' was not declared in this scope; did you mean 'JSON_OBJECT'? is nonsensical. This patch tweaks dump_scope to detect unscoped enums, and to use the enclosing namespace for them, so that the CONST_DECL is dumped as "json::JSON_OBJECT". This changes the output for the above so that it refers to the namespace, fixing the issue: <source>:8:3: error: 'JSON_OBJECT' was not declared in this scope; did you mean 'json::JSON_OBJECT'? 9 | JSON_OBJECT; | ^~~~~~~~~~~ | json::JSON_OBJECT <source>3:10: note: 'json::JSON_OBJECT' declared here 3 | enum { JSON_OBJECT }; | ^~~~~~~~~~~ The patch also fixes scope-printing for values within scoped enums. To exercise this, the patch extends the scanner for namespaces for exact matches for a name, so that we also scan inside scoped enums, to cover the case where someone doesn't supply the scope. Hence with the patch given e.g.: enum class vegetable { CARROT, TURNIP }; we're able to offer e.g.: suggestions-scoped-enums.C:50:3: error: 'CARROT' was not declared in this scope; did you mean 'vegetable::CARROT'? 50 | CARROT; | ^~~~~~ | vegetable::CARROT and this exercises the code path above. The patch updates dump_scope for scoped enums so that we print the scope when printing the value ("vegetable::CARROT"), rather than just the name of the value ("CARROT"). Finally, the patch adds spell-corrections within a scoped enum, giving e.g.: suggestions-scoped-enums.C:18:14: error: 'TURNUP' is not a member of 'vegetable'; did you mean 'TURNIP'? 18 | vegetable::TURNUP; | ^~~~~~ | TURNIP gcc/cp/ChangeLog: PR c++/88121 * cp-name-hint.h (suggest_alternative_in_scoped_enum): New decl. * error.c (dump_scope): Ensure that we print any scope for values of unscoped enums. Print the scope of values of scoped enums. (qualified_name_lookup_error): Offer suggestions for failures within scoped enums by calling suggest_alternative_in_scoped_enum. * name-lookup.c (class namespace_hints): Update comment to mention scoped enums. (namespace_hints::namespace_hints): Call maybe_add_candidate_for_scoped_enum. (namespace_hints::maybe_add_candidate_for_scoped_enum): New member (suggest_alternatives_for): Update comment to mention scoped enums. (suggest_alternative_in_scoped_enum): New function. gcc/testsuite/ChangeLog: PR c++/88121 * g++.dg/lookup/suggestions-scoped-enums.C: New test. * g++.dg/lookup/suggestions-unscoped-enums.C: New test. From-SVN: r266644
Showing
Please
register
or
sign in
to comment