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

            Bug ID: 90220
           Summary: std::any_cast misbehaves for function and array types
           Product: gcc
           Version: 8.3.1
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

This valid program fails to compile:

#include <any>
int main() {
  std::any a;
  std::any_cast<void()>(&a);
}

In file included from a.cc:1:
/home/jwakely/gcc/9/include/c++/9.0.1/any: In instantiation of '_ValueType*
std::any_cast(std::any*) [with _ValueType = void()]':
a.cc:4:27:   required from here
/home/jwakely/gcc/9/include/c++/9.0.1/any:544:9: error: invalid static_cast
from type 'void*' to type 'void (*)()'
  544 |  return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The contained value can never be a function type, so any_cast can just return
nullptr if !is_object_v<_ValueType>.

This program compiles but fails the assertion:

#include <any>
#include <assert.h>
#include <typeinfo>

int main()
{
  int arr[3];
  std::any a(arr);
  assert( a.type() == typeid(int*) ); // contained value is decayed

  int (*p)[3] = std::any_cast<int[3]>(&a);
  assert( p == nullptr );
}

a.out: b.cc:12: int main(): Assertion `p == nullptr' failed.
Aborted (core dumped)

The problem is that __any_caster uses decay_t<_ValueType> to see if the manager
function matches the requested type. That's wrong, because decaying should only
happen on construction, not when accessing the value with any_cast.

Reply via email to