On 11/21/18 8:35 AM, David Malcolm wrote:
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, as gcc 9 now 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.
The root cause is that dump_scope doesn't print anything when called for
CONST_DECL in a namespace: the scope is an ENUMERAL_TYPE, rather than
a namespace.
Although that's only true for unscoped enums.
This patch tweaks dump_scope to detect ENUMERAL_TYPE, and to use the
enclosing namespace, so that the CONST_DECL is dumped as
"json::JSON_OBJECT".
@@ -182,6 +182,12 @@ dump_scope (cxx_pretty_printer *pp, tree scope, int flags)
if (scope == NULL_TREE)
return;
+ /* Enum values will be CONST_DECL with an ENUMERAL_TYPE as their
+ "scope". Use CP_TYPE_CONTEXT of the ENUMERAL_TYPE, so as to
+ print the enclosing namespace. */
+ if (TREE_CODE (scope) == ENUMERAL_TYPE)
+ scope = CP_TYPE_CONTEXT (scope);
This needs to handle scoped enums differently.
diff --git a/gcc/testsuite/g++.dg/lookup/suggestions-scoped-enums.C
b/gcc/testsuite/g++.dg/lookup/suggestions-scoped-enums.C
new file mode 100644
index 0000000..2bf3ed6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/suggestions-scoped-enums.C
@@ -0,0 +1,13 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-fdiagnostics-show-caret" }
+
+enum class vegetable { CARROT, TURNIP };
+
+void misspelled_value_in_scoped_enum ()
+{
+ vegetable::TURNUP; // { dg-error "'TURNUP' is not a member of 'vegetable'" }
+ /* { dg-begin-multiline-output "" }
+ vegetable::TURNUP;
+ ^~~~~~
+ { dg-end-multiline-output "" } */
+}
I don't see any suggestion in the expected output, and would hope for it
to suggest vegetable::TURNIP.
Jason