public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/96286] New: Unhelpful errors after a failed static_assert
@ 2020-07-22 15:00 redi at gcc dot gnu.org
  2021-07-15 10:44 ` [Bug c++/96286] " redi at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2020-07-22 15:00 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 96286
           Summary: Unhelpful errors after a failed static_assert
           Product: gcc
           Version: 10.1.1
            Status: UNCONFIRMED
          Keywords: diagnostic
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

template<typename T>
struct S
{
  static_assert( sizeof(T) < 4, "smol" );

  char* p = new char[3 - sizeof(T)];
};

S<long long> s;


GCC gives two errors:

sa.C: In instantiation of ‘struct S<long long int>’:
sa.C:9:14:   required from here
sa.C:4:28: error: static assertion failed: smol
    4 |   static_assert( sizeof(T) < 4, "smol" );
      |                  ~~~~~~~~~~^~~
sa.C: In instantiation of ‘constexpr S<long long int>::S()’:
sa.C:9:14:   required from here
sa.C:6:24: error: size ‘18446744073709551611’ of array exceeds maximum object
size ‘9223372036854775807’
    6 |   char* p = new char[3 - sizeof(T)];
      |                      ~~^~~~~~~~~~~

The second error is unhelpful. I know the array size is invalid, that's why I
put the static assertion there.

Clang just says:

sa.C:4:3: error: static_assert failed due to requirement 'sizeof(long long) <
4' "smol"
  static_assert( sizeof(T) < 4, "smol" );
  ^              ~~~~~~~~~~~~~
sa.C:9:14: note: in instantiation of template class 'S<long long>' requested
here
S<long long> s;
             ^
1 error generated.

EDG says:

"sa.C", line 4: error: static assertion failed with "smol"
    static_assert( sizeof(T) < 4, "smol" );
    ^
          detected during instantiation of class "S<T> [with T=long long]" at
                    line 9

1 error detected in the compilation of "sa.C".

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

* [Bug c++/96286] Unhelpful errors after a failed static_assert
  2020-07-22 15:00 [Bug c++/96286] New: Unhelpful errors after a failed static_assert redi at gcc dot gnu.org
@ 2021-07-15 10:44 ` redi at gcc dot gnu.org
  2021-07-15 10:56 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-15 10:44 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This is a major pain the backside for trying to give good diagnostics for
std::get<T>(tuple<Types...>&). I want to stop with a "clear" static assertion
like:

In file included from
/home/jwakely/src/gcc/gcc/libstdc++-v3/testsuite/20_util/tuple/element_access/101427.cc:3:
/home/jwakely/gcc/12/include/c++/12.0.0/tuple: In instantiation of 'constexpr
std::size_t std::__find_uniq_type_in_pack() [with _Tp = long int; _Types =
{float, int, int}; std::size_t = long unsigned int]':
/home/jwakely/gcc/12/include/c++/12.0.0/tuple:1452:63:   required from
'constexpr _Tp& std::get(std::tuple<_UTypes ...>&) [with _Tp = long int; _Types
= {float, int, int}]'
/home/jwakely/src/gcc/gcc/libstdc++-v3/testsuite/20_util/tuple/element_access/101427.cc:7:22:
  required from here
/home/jwakely/gcc/12/include/c++/12.0.0/tuple:1441:27: error: static assertion
failed: the type T in std::get<T> must occur exactly once in the tuple
 1441 |       static_assert(__idx >= 0,
      |                     ~~~~~~^~~~

But G++ insists on continuing past that point, returning an out-of-range index
which causes 200 lines of errors because std::get<SIZE_MAX>(t) is invalid.

I know it's invalid, that's why I made the static assertion fail. Just stop.

I now have to jump through ridiculous hoops to add additional code to munge the
invalid value into some other value to stop the 200 lines of noise.

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

* [Bug c++/96286] Unhelpful errors after a failed static_assert
  2020-07-22 15:00 [Bug c++/96286] New: Unhelpful errors after a failed static_assert redi at gcc dot gnu.org
  2021-07-15 10:44 ` [Bug c++/96286] " redi at gcc dot gnu.org
@ 2021-07-15 10:56 ` redi at gcc dot gnu.org
  2021-07-15 11:21 ` redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-15 10:56 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
It also doesn't help that the compiler thwarts my attempt to trigger errors
earlier like so:

  // Return index of _Tp in _Types.
  // Ill-formed if _Tp doesn't occur exactly once in _Types.
  template<typename _Tp, typename... _Types>
    constexpr size_t
    __find_uniq_type_in_pack()
    {
      constexpr ptrdiff_t __idx = std::__find_type_in_pack<_Tp, _Types...>();
      static_assert(__idx >= 0,
          "the type T in std::get<T> must occur exactly once in the tuple");
      return size_t{__idx};
    }

The return statement *should* be an ill-formed narrowing conversion, but G++
(and Clang) think that because I'm in a system header we probably wanted to
ignore that, so we return a huge value and get 200 lines of errors again.

Maybe this will work?
    {
      constexpr ptrdiff_t __idx = std::__find_type_in_pack<_Tp, _Types...>();
      static_assert(__idx >= 0,
          "the type T in std::get<T> must occur exactly once in the tuple");
      if (__idx >= 0)
        return __idx;
      __builtin_unreachable();
    }

No, now I get 200 lines telling me that the I in std::get<I> is not a constant
expression because of __builtin_unreachable.

OK, let's try       return enable_if_t<__idx >= 0, size_t>{__idx};

This prints "error: no type named 'type' in 'struct std::enable_if'" as
expected, but then 200 lines telling me std::get<I> is not a constant
expression because it flows off the end of the function.

Why is the compiler even doing overload resolution for std::get<I> if I is an
invalid constant expression?! It's not going to match any overload!

It shouldn't be this hard. Just stop compiling already.

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

* [Bug c++/96286] Unhelpful errors after a failed static_assert
  2020-07-22 15:00 [Bug c++/96286] New: Unhelpful errors after a failed static_assert redi at gcc dot gnu.org
  2021-07-15 10:44 ` [Bug c++/96286] " redi at gcc dot gnu.org
  2021-07-15 10:56 ` redi at gcc dot gnu.org
@ 2021-07-15 11:21 ` redi at gcc dot gnu.org
  2021-08-30 21:27 ` cvs-commit at gcc dot gnu.org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-15 11:21 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #2)
> Why is the compiler even doing overload resolution for std::get<I> if I is
> an invalid constant expression?! It's not going to match any overload!

This part is now PR 101460

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

* [Bug c++/96286] Unhelpful errors after a failed static_assert
  2020-07-22 15:00 [Bug c++/96286] New: Unhelpful errors after a failed static_assert redi at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2021-07-15 11:21 ` redi at gcc dot gnu.org
@ 2021-08-30 21:27 ` cvs-commit at gcc dot gnu.org
  2021-08-31 21:48 ` jason at gcc dot gnu.org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2021-08-30 21:27 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:8960a29b18b830ff0490b7f52051903fba472e45

commit r12-3236-g8960a29b18b830ff0490b7f52051903fba472e45
Author: Jason Merrill <jason@redhat.com>
Date:   Sun Aug 29 18:17:22 2021 -0400

    c++: limit instantiation with ill-formed class [PR96286]

    I noticed that after the static_assert failures in lwg3466.cc, we got
    various follow-on errors because we went ahead and tried to instantiate the
    promise<T> member functions even after instantiating the class itself ran
    into problems.  Interrupting instantiation of the class itself seems likely
    to cause error-recovery problems, but preventing instantiation of member
    functions seems strictly better for error-recovery.

    This doesn't fix any of the specific testcases in PR96286, but addresses
    part of that problem space.

            PR c++/96286

    gcc/cp/ChangeLog:

            * cp-tree.h (struct lang_type): Add erroneous bit-field.
            (CLASSTYPE_ERRONEOUS): New.
            * pt.c (limit_bad_template_recursion): Check it.
            (instantiate_class_template_1): Set it.

    libstdc++-v3/ChangeLog:

            * testsuite/30_threads/promise/requirements/lwg3466.cc:
            Remove dg-prune-outputs.

    gcc/testsuite/ChangeLog:

            * g++.dg/template/access2.C: Split struct A.

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

* [Bug c++/96286] Unhelpful errors after a failed static_assert
  2020-07-22 15:00 [Bug c++/96286] New: Unhelpful errors after a failed static_assert redi at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2021-08-30 21:27 ` cvs-commit at gcc dot gnu.org
@ 2021-08-31 21:48 ` jason at gcc dot gnu.org
  2021-09-02 12:27 ` jason at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jason at gcc dot gnu.org @ 2021-08-31 21:48 UTC (permalink / raw)
  To: gcc-bugs

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

Jason Merrill <jason at gcc dot gnu.org> changed:

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

--- Comment #5 from Jason Merrill <jason at gcc dot gnu.org> ---
(In reply to CVS Commits from comment #4)
>     c++: limit instantiation with ill-formed class [PR96286]

This change and the one for PR92193 improve our limiting of recursive
instantiation leading to unhelpful errors, but they don't help with the vector
89164 testcase you pointed me at, because the static_assert is buried deep in
the call stack.

wa.ii: In instantiation of ‘constexpr bool std::__check_constructible() [with
_ValueType = X; _Tp = X&]’:
wa.ii:20407:119:   required from ‘_ForwardIterator
std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with
_InputIterator = X*; _ForwardIterator = X*]’
wa.ii:20560:37:   required from ‘constexpr _ForwardIterator
std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator,
std::allocator<_Tp>&) [with _InputIterator = X*; _ForwardIterator = X*; _Tp =
X]’
wa.ii:22118:33:   required from ‘constexpr void std::vector<_Tp,
_Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator,
std::forward_iterator_tag) [with _ForwardIterator = X*; _Tp = X; _Alloc =
std::allocator<X>]’
wa.ii:21612:23:   required from here
wa.ii:20342:56: error: static assertion failed: result type must be
constructible from input type

and then later we get

wa.ii: In instantiation of ‘constexpr void std::_Construct(_Tp*, _Args&& ...)
[with _Tp = X; _Args = {X&}]’:
wa.ii:20357:21:   required from ‘constexpr _ForwardIterator
std::__do_uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with
_InputIterator = X*; _ForwardIterator = X*]’
wa.ii:20558:30:   required from ‘constexpr _ForwardIterator
std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator,
std::allocator<_Tp>&) [with _InputIterator = X*; _ForwardIterator = X*; _Tp =
X]’
wa.ii:22118:33:   required from ‘constexpr void std::vector<_Tp,
_Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator,
std::forward_iterator_tag) [with _ForwardIterator = X*; _Tp = X; _Alloc =
std::allocator<X>]’
wa.ii:21612:23:   required from here
wa.ii:13010:21: error: no matching function for call to ‘construct_at(X*&, X&)’

but _Construct was queued for instantiation before we hit the static_assert; it
was prompted by an earlier line in __uninitialized_copy_a than the one that led
to the instantiation of __check_constructible.

I get better results if I add the static_assert to __uninitialized_copy_a, so
we hit it before queuing any further instantiations.

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

* [Bug c++/96286] Unhelpful errors after a failed static_assert
  2020-07-22 15:00 [Bug c++/96286] New: Unhelpful errors after a failed static_assert redi at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2021-08-31 21:48 ` jason at gcc dot gnu.org
@ 2021-09-02 12:27 ` jason at gcc dot gnu.org
  2021-09-02 12:27 ` jason at gcc dot gnu.org
  2021-09-02 12:56 ` redi at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: jason at gcc dot gnu.org @ 2021-09-02 12:27 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Jason Merrill <jason at gcc dot gnu.org> ---
Created attachment 51402
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51402&action=edit
patch to silence constexpr issues with erroneous functions

Here are a couple of other commits I tried to reduce error cascades, but they
also didn't help with the vector testcase.

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

* [Bug c++/96286] Unhelpful errors after a failed static_assert
  2020-07-22 15:00 [Bug c++/96286] New: Unhelpful errors after a failed static_assert redi at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2021-09-02 12:27 ` jason at gcc dot gnu.org
@ 2021-09-02 12:27 ` jason at gcc dot gnu.org
  2021-09-02 12:56 ` redi at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: jason at gcc dot gnu.org @ 2021-09-02 12:27 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Jason Merrill <jason at gcc dot gnu.org> ---
Created attachment 51403
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51403&action=edit
patch to stop compiling a function after static_assert

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

* [Bug c++/96286] Unhelpful errors after a failed static_assert
  2020-07-22 15:00 [Bug c++/96286] New: Unhelpful errors after a failed static_assert redi at gcc dot gnu.org
                   ` (6 preceding siblings ...)
  2021-09-02 12:27 ` jason at gcc dot gnu.org
@ 2021-09-02 12:56 ` redi at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2021-09-02 12:56 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jason Merrill from comment #5)
> I get better results if I add the static_assert to __uninitialized_copy_a,
> so we hit it before queuing any further instantiations.

I actually need to check the same assertion in that function anyway, for the
constexpr std::vector case.

I'll see how the diagnostics look on that branch after rebasing on trunk, to
get your recent G++ changes. Thanks.

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

end of thread, other threads:[~2021-09-02 12:56 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-22 15:00 [Bug c++/96286] New: Unhelpful errors after a failed static_assert redi at gcc dot gnu.org
2021-07-15 10:44 ` [Bug c++/96286] " redi at gcc dot gnu.org
2021-07-15 10:56 ` redi at gcc dot gnu.org
2021-07-15 11:21 ` redi at gcc dot gnu.org
2021-08-30 21:27 ` cvs-commit at gcc dot gnu.org
2021-08-31 21:48 ` jason at gcc dot gnu.org
2021-09-02 12:27 ` jason at gcc dot gnu.org
2021-09-02 12:27 ` jason at gcc dot gnu.org
2021-09-02 12:56 ` redi 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).