[cfe-dev] __PRETTY_FUNCTION__ output loses enum type info for non-enumerated values

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Tue Sep 4 13:30:02 PDT 2018


On Tue, 4 Sep 2018 at 09:09, will wray via cfe-dev <cfe-dev at lists.llvm.org>
wrote:

> A request to change Clang's __PRETTY_FUNCTION__ output to fix an issue.
>
> The code used in pretty function is also used to generate debug info in
> DWARF etc
> .
> (I believe). See, for instance the comment on this bug report:
> https://sourceware.org/bugzilla/show_bug.cgi?id=21492#c1
>
>> Clang shows these arguments with the same DW_AT_name, X<1>, but they're
>> distinct types
>
>
> https://godbolt.org/z/0Ik0Hl
> Pretty function output, for auto... args
> (variadic just so that outputs display together):
>
> template <auto... V>
> constexpr char const* auto_name()
> {
> return __PRETTY_FUNCTION__;
> }
>
> enum e { a, b, c=b };
> enum class E { a, b, c=b };
>
> char const* nameU() { return auto_name<a, b, c, e(3)>(); }
> char const* nameS() { return auto_name<E::a, E::b, E::c, E{3}>(); }
>
>
> Gives output with these strings embedded;
>
> nameU:
> <a, b, b, 3>
>
> nameS:
> <E::a, E::b, E::b, 3>
>
>
> The first two enumerated values, a & b, are returned with no loss of type
> info as a, b.
> The next enumerated value, c, is a duplicate label for b's value, and is
> reported as b.
> The final value is not enumerated - there is no enum label with value 3 -
> it is reported with an unnecessary loss of type info
> as plain digits 3.
>
> The non-enumerated value should be reported with a cast or constructor:
>
> unscoped e: 3 -> (e)3 or e(3)
>
>   scoped   E: 3 -> (E)3 or E(3) or E{3}
>
>  (init-list E{3} only for scoped enum and only since c++17)
>
>
> Question 1:
>
> Will it be acceptable to change the output for non-enumerated values as so?
>

In the case where the template parameter involves a deduced type (`auto` or
`decltype(auto)` or eventually a deduced template specialization type), it
would make a lot of sense to include the actual type in the printed
template argument if it differs from the type of the formatted argument
string. But I think we should leave out the type in all other cases, as it
would make the template argument string more verbose without (necessarily)
providing any more information.

This will retain type info and allow round-trip without loss.
> Either C-style cast (e)3  or  function-cast / type-constructor e(3) - seem
> ok
> (gcc uses C-style casts and Clang uses this same style in source labels).
>
> For the duplicate-valued labels case there is no loss of type info,
> but there is a loss of information about the label used for the auto arg.
> Presumably, the code works from the supplied underlying-type value
> and picks the first label with the given value. I'd guess that Clang knows
> the label used in a direct instantiation and could return it in that case.
> (c.f. named member-pointer args have to retain the id for reporting).
>

In the case of duplicated enumerators, there simply is no distinction
between 'b' and 'c' -- they are both merely names for the value 1 of type
'e'. auto_name<b>() and auto_name<c>() are the same function and therefore
must return the same string.


> Question 2:
>
> Is it possible / acceptable to retain the label in the duplicate enum
> value case?
>

No, per the above, we cannot and must not do that.

Can anyone point me to the relevant code?
>

This is printIntegral, at the top of lib/AST/TemplateBase.cpp. The "else"
case at the bottom would need to print out additional text representing the
cast when needed.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180904/d50eb77b/attachment.html>


More information about the cfe-dev mailing list