public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/103600] New: Cannot use typeid result in constant expressions
@ 2021-12-07  9:38 redi at gcc dot gnu.org
  2021-12-07  9:51 ` [Bug c++/103600] " pinskia at gcc dot gnu.org
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2021-12-07  9:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

            Bug ID: 103600
           Summary: Cannot use typeid result in constant expressions
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

This should compile:

#include <typeinfo>
#if __cpp_lib_constexpr_typeinfo
constexpr bool b = typeid(int) == typeid(long);
#else
constexpr bool b = &typeid(int) == &typeid(long);
#endif

But GCC trunk (12.0.0 20211125) says:

ti.C:5:33: error: '(((const std::type_info*)(& _ZTIi)) == ((const
std::type_info*)(& _ZTIl)))' is not a constant expression
    5 | constexpr bool b = &typeid(int) == &typeid(long);
      |                    ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~



This blocks
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1328r1.html (Making
std::type_info::operator== constexpr) 

With the library changes in place compiling with -std=gnu++23 gives:

ti.C:3:32:   in 'constexpr' expansion of '((const std::type_info*)(&
_ZTIi))->std::type_info::operator==(_ZTIl)'
ti.C:3:46: error: accessing value of '_ZTIi' through a 'const std::type_info'
glvalue in a constant expression
    3 | constexpr bool b = typeid(int) == typeid(long);
      |                                              ^



Using clang++ -std=c++2b the same patched libstdc++ code gives:

ti.C:3:16: error: constexpr variable 'b' must be initialized by a constant
expression
constexpr bool b = typeid(int) == typeid(long);
               ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/jwakely/gcc/latest/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/typeinfo:195:9:
note: read of object 'typeid(int).__name' whose value is not known
    if (__name == __arg.__name)
        ^
ti.C:3:32: note: in call to '&typeid(int)->operator==(typeid(long))'
constexpr bool b = typeid(int) == typeid(long);
                               ^

Which presumably means that the RTTI for built-in types (defined in
libsupc++/fundamental_type_info.cc) needs to be made visible during constant
evaluation.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
@ 2021-12-07  9:51 ` pinskia at gcc dot gnu.org
  2021-12-07  9:52 ` pinskia at gcc dot gnu.org
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-12-07  9:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |102551

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I think this is a dup of bug 102551.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102551
[Bug 102551] Failing compile-time comparison of std::type_info addresses

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
  2021-12-07  9:51 ` [Bug c++/103600] " pinskia at gcc dot gnu.org
@ 2021-12-07  9:52 ` pinskia at gcc dot gnu.org
  2021-12-07 10:01 ` redi at gcc dot gnu.org
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-12-07  9:52 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Or at least the 
constexpr bool b = &typeid(int) == &typeid(long);

example.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
  2021-12-07  9:51 ` [Bug c++/103600] " pinskia at gcc dot gnu.org
  2021-12-07  9:52 ` pinskia at gcc dot gnu.org
@ 2021-12-07 10:01 ` redi at gcc dot gnu.org
  2021-12-07 13:23 ` jakub at gcc dot gnu.org
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2021-12-07 10:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2021-12-07
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Ah yes thanks. The requirement to make the RTTI visible during constant
evaluation is new info.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2021-12-07 10:01 ` redi at gcc dot gnu.org
@ 2021-12-07 13:23 ` jakub at gcc dot gnu.org
  2021-12-07 13:47 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-12-07 13:23 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hubicka at gcc dot gnu.org,
                   |                            |jakub at gcc dot gnu.org,
                   |                            |jason at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
We handle e.g.
constexpr auto x = &typeid(int) == &typeid(int);
or
int a, b;
constexpr auto y = &a == &b;
The former by the (cmp @0 @0) folding in match.pd, the latter by
the address_compare match.pd patterns.
But, we already punt on e.g.
template <int N>
inline int a = N;
constexpr auto c = &a<0> == &a<1>;
because address_compare -> equal_address_to punts on those,
decl_binds_to_current_def_p is false (they are comdat and can end up being
defined from some other TU etc.).
And similarly it punts in the
&typeid(int) == &typeid(long)
case, neither _ZTIi nor _ZTIl are defined in the current TU (both are defined
in libstdc++) and the code attempts to play safe, say if the actual definitions
would be aliases of each other etc.

I guess at least for constexpr evaluation we want to have some C++ rules, both
for typeid vars - dunno if we can rely on the get_tinfo_decl_direct created
vars to be always different if they aren't the same VAR_DECL, or if we need to
e.g. compute the name and compare those, or for stuff like inline vars or
variable templates.  And the question is if cxx_eval_binary_expression should
for EQ_EXPR/NE_EXPR repeat what the match.pd address_compare simplification
does with its own address_compare, or if it should temporarily set some
langhook and
let address_compare use that langhook to handle the special cases, or if a
langhook should handle some of those cases always for C++.

Another case is the typeid(int) == typeid(long) comparison, operator== is I
think
    bool operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT
    {
      return ((__name == __arg.__name)                        
              || (__name[0] != '*' &&                         
                  __builtin_strcmp (__name, __arg.__name) == 0));
    }
so we'd need to be able to constant fold during constexpr evaluation
typeid(int).__name to &_ZTSi when the typeinfo isn't defined locally and
handle &_ZTSwhatever similarly to &_ZTIwhatever, but further we even need to
constant fold reading from those strings even when they aren't local..

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2021-12-07 13:23 ` jakub at gcc dot gnu.org
@ 2021-12-07 13:47 ` redi at gcc dot gnu.org
  2021-12-07 16:44 ` jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2021-12-07 13:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The new definition of operator== will be something like:

#if __GXX_TYPEINFO_EQUALITY_INLINE || __cplusplus > 202002L
  _GLIBCXX23_CONSTEXPR inline bool
  type_info::operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT
  {
    if (__name == __arg.__name)
      return true;

    if (!std::__is_constant_evaluated())
      return false;

#if !__GXX_TYPEINFO_EQUALITY_INLINE
    // ABI requires comparisons to be non-inline.
    return __equal(__arg);
#elif !__GXX_MERGED_TYPEINFO_NAMES
    // Need to do string comparison.
    return __name[0] != '*' && __builtin_strcmp (__name, __arg.name()) == 0;
#else
    return false;
#endif
  }
# endif


i.e. no strcmp for the constant evaluation case. During constant evaluation I
think we only need to handle types that are completely defined in the current
TU, so we can ignore aliasing of _ZTi symbols, and we can ignore the problem of
non-unique std::type_info objects. Within the TU they will be unique.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2021-12-07 13:47 ` redi at gcc dot gnu.org
@ 2021-12-07 16:44 ` jakub at gcc dot gnu.org
  2021-12-08  0:30 ` redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-12-07 16:44 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |jakub at gcc dot gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 51945
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51945&action=edit
gcc12-pr103600.patch

Untested patch that should make typeid(x) == typeid(y) and &typeid(x) ==
&typeid(y) work, but don't want to duplicate <typeinfo>, so for a testcase I'd
need to wait (at least for the former case) until the libstdc++ change lands.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2021-12-07 16:44 ` jakub at gcc dot gnu.org
@ 2021-12-08  0:30 ` redi at gcc dot gnu.org
  2022-01-03 10:24 ` cvs-commit at gcc dot gnu.org
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2021-12-08  0:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Created attachment 51946
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51946&action=edit
libstdc++: Implement P1328 "Making std::type_info::operator== constexpr"

Jakub, that patch works for me. Here's the libstdc++ patch to make operator==
constexpr, which passes with your patch applied.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
                   ` (6 preceding siblings ...)
  2021-12-08  0:30 ` redi at gcc dot gnu.org
@ 2022-01-03 10:24 ` cvs-commit at gcc dot gnu.org
  2022-01-03 10:34 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-01-03 10:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

--- Comment #8 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:134442b2178a164ed4580255a0de007dda19b855

commit r12-6183-g134442b2178a164ed4580255a0de007dda19b855
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Mon Jan 3 11:21:00 2022 +0100

    c++: Support &typeid(x) == &typeid(y) and typeid(x) == typeid(y) in
constant evaluation [PR103600]

    If the tinfo vars are emitted in the current TU, they are emitted at the
end
    of the compilation, and for some types they are exported from
    libstdc++/libsupc++ and not emitted in the current TU at all.

    The following patch allows constant folding of comparisons of typeid
    addresses and makes it possible to implement P1328R1 - making type_info
    operator== constexpr (Jonathan has a patch for that).

    As mentioned in the PR, the varpool/middle-end code is trying to be
    conservative with address comparisons of different vars if those vars
    don't bind locally, because of possible aliases in other TUs etc.
    and so while match.pd folds &typeid(int) == &typeid(int) because
    it is equality comparison with the same operands, for different typeids
    it doesn't fold it.

    On Wed, Dec 08, 2021 at 08:53:03AM -0500, Jason Merrill wrote:
    > Would it make sense to assume that DECL_ARTIFICIAL variables can't be
    > aliases?  If not, could we have some way of marking a variable as
    > non-aliasing, perhaps an attribute?

    I think DECL_ARTIFICIAL vars generally can overlap.

    The following patch adds a GCC internal attribute "non overlapping"
    and uses it in symtab_node::equal_address_to.
    Not sure what plans has Honza in that area and whether it would be useful
    to make the attribute public and let users assert that some variable will
    never overlap with other variables, won't have aliases etc.

    > During constant evaluation, the operator== could compare the type_info
    > address instead of the __name address, reducing this to the previous
    > problem.

    Ah, indeed, good idea.  FYI, clang++ seems to constant fold
    &typeid(x) != &typeid(y) already, so Jonathan could use it even for
    clang++ in the constexpr operator==.  But it folds even
    extern int &a, &b;
    constexpr bool c = &a != &b;
    regardless of whether some other TU has
    int a;
    int b __attribute__((alias (a));
    or not.

    2022-01-03  Jakub Jelinek  <jakub@redhat.com>

            PR c++/103600
    gcc/
            * symtab.c (symtab_node::equal_address_to): Return 0 if one of
            VAR_DECLs has "non overlapping" attribute and rs1 != rs2.
    gcc/c-family/
            * c-attribs.c (handle_non_overlapping_attribute): New function.
            (c_common_attribute_table): Add "non overlapping" attribute.
    gcc/cp/
            * rtti.c (get_tinfo_decl_direct): Add "non overlapping" attribute
            to DECL_TINFO_P VAR_DECLs.
    gcc/testsuite/
            * g++.dg/cpp0x/constexpr-typeid2.C: New test.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
                   ` (7 preceding siblings ...)
  2022-01-03 10:24 ` cvs-commit at gcc dot gnu.org
@ 2022-01-03 10:34 ` jakub at gcc dot gnu.org
  2022-01-06 14:49 ` ppalka at gcc dot gnu.org
  2022-11-03 13:29 ` ppalka at gcc dot gnu.org
  10 siblings, 0 replies; 12+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-01-03 10:34 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Sorry for the delay, I've missed Honza's
https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586501.html
mail (didn't reach my mailbox but is in the archives).

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
                   ` (8 preceding siblings ...)
  2022-01-03 10:34 ` jakub at gcc dot gnu.org
@ 2022-01-06 14:49 ` ppalka at gcc dot gnu.org
  2022-11-03 13:29 ` ppalka at gcc dot gnu.org
  10 siblings, 0 replies; 12+ messages in thread
From: ppalka at gcc dot gnu.org @ 2022-01-06 14:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|102551                      |
                 CC|                            |fchelnokov at gmail dot com

--- Comment #10 from Patrick Palka <ppalka at gcc dot gnu.org> ---
*** Bug 102551 has been marked as a duplicate of this bug. ***


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102551
[Bug 102551] Failing compile-time comparison of std::type_info addresses

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/103600] Cannot use typeid result in constant expressions
  2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
                   ` (9 preceding siblings ...)
  2022-01-06 14:49 ` ppalka at gcc dot gnu.org
@ 2022-11-03 13:29 ` ppalka at gcc dot gnu.org
  10 siblings, 0 replies; 12+ messages in thread
From: ppalka at gcc dot gnu.org @ 2022-11-03 13:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103600

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ppalka at gcc dot gnu.org
             Status|ASSIGNED                    |RESOLVED
   Target Milestone|---                         |12.0
         Resolution|---                         |FIXED

--- Comment #11 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Thus fixed since GCC 12

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-11-03 13:29 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-07  9:38 [Bug c++/103600] New: Cannot use typeid result in constant expressions redi at gcc dot gnu.org
2021-12-07  9:51 ` [Bug c++/103600] " pinskia at gcc dot gnu.org
2021-12-07  9:52 ` pinskia at gcc dot gnu.org
2021-12-07 10:01 ` redi at gcc dot gnu.org
2021-12-07 13:23 ` jakub at gcc dot gnu.org
2021-12-07 13:47 ` redi at gcc dot gnu.org
2021-12-07 16:44 ` jakub at gcc dot gnu.org
2021-12-08  0:30 ` redi at gcc dot gnu.org
2022-01-03 10:24 ` cvs-commit at gcc dot gnu.org
2022-01-03 10:34 ` jakub at gcc dot gnu.org
2022-01-06 14:49 ` ppalka at gcc dot gnu.org
2022-11-03 13:29 ` ppalka at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).