Bug 32159 - [gdb/symtab] gdb cannot print named constant as member of enumeration type
Summary: [gdb/symtab] gdb cannot print named constant as member of enumeration type
Status: NEW
Alias: None
Product: gdb
Classification: Unclassified
Component: symtab (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: 16106
  Show dependency treegraph
 
Reported: 2024-09-10 13:08 UTC by Tom de Vries
Modified: 2024-09-13 20:55 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2024-09-10 13:08:30 UTC
Consider this test-case, using two ways to get to val1:
...
$ cat test.c
namespace ns
{
  enum e
  {
    val1 = 0x1,
  };
}

int
main (void)
{
  return (int)ns::e::val1 + (int)ns::val1;
}
$ g++ -g test.c
$ ./a.out ; echo $?
2
...

In gdb, we have:
...
$ gdb -q -batch a.out -ex "print ns::val1"
$1 = ns::val1
...
but not:
...
$ gdb -q -batch a.out -ex "print ns::e::val1"
`ns::e' is not defined as an aggregate type.
...

In contrast, with lldb we have:
...
$ lldb -batch a.out -o "p ns::e::val1"
(lldb) target create "a.out"
Current executable set to '/home/vries/gdb/a.out' (x86_64).
(lldb) p ns::e::val1
(ns::e) $0 = val1
...
but not:
...
$ lldb -batch a.out -o "p ns::val1"
(lldb) target create "a.out"
Current executable set to '/home/vries/gdb/a.out' (x86_64).
(lldb) p ns::val1
error: <user expression 0>:1:5: no member named 'val1' in namespace 'ns'
ns::val1
~~~~^
...
Comment 1 Tom Tromey 2024-09-10 15:07:56 UTC
> print ns::e::val1

I did not know this is valid C++.
Comment 2 Tom Tromey 2024-09-11 18:23:52 UTC
FWIW, this one is probably not a regression, and also may
require adding a second symbol in the full reader as well.
Though perhaps it would be better to change the parser
to look up "ns::e" and then search the enum type itself
for "val1", eliminating the need for any new entries or symbols.
Comment 3 Tom de Vries 2024-09-11 21:22:13 UTC
(In reply to Tom Tromey from comment #2)
> FWIW, this one is probably not a regression, and also may
> require adding a second symbol in the full reader as well.
> Though perhaps it would be better to change the parser
> to look up "ns::e" and then search the enum type itself
> for "val1", eliminating the need for any new entries or symbols.

Using this patch:
...
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index ca411dc0f5b..98b505793d4 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -1129,7 +1129,7 @@ qualified_name:	TYPENAME COLONCOLON name
 			{
 			  struct type *type = $1.type;
 			  type = check_typedef (type);
-			  if (!type_aggregate_p (type))
+			  if (!type_aggregate_p (type)
+                             && type->code () != TYPE_CODE_ENUM)
 			    error (_("`%s' is not defined as an aggregate type."),
 				   TYPE_SAFE_NAME (type));
 
diff --git a/gdb/valops.c b/gdb/valops.c
index 427fbb1ad61..00ca7b61a28 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3394,9 +3394,6 @@ enum_constant_from_type (struct type *type, const char *name)
   int i;
   int name_len = strlen (name);
 
-  gdb_assert (type->code () == TYPE_CODE_ENUM
-	      && type->is_declared_class ());
-
   for (i = TYPE_N_BASECLASSES (type); i < type->num_fields (); ++i)
     {
       const char *fname = type->field (i).name ();
...
we get:
...
$ gdb -q -batch -readnow a.out -ex "print ns::e::val1"
$1 = ns::val1
...
Comment 4 Tom de Vries 2024-09-11 23:48:34 UTC
(In reply to Tom Tromey from comment #1)
> > print ns::e::val1
> 
> I did not know this is valid C++.

I tried to find a reference for this, and here ( https://en.cppreference.com/w/cpp/language/enum ) I found:
...
struct X
{
    enum direction { left = 'l', right = 'r' };
};
 
int a = X::direction::left; // allowed only in C++11 and later
...