Bug 92856 - incorrectly accepts invalid C++11 braced initialisation of double from long double
Summary: incorrectly accepts invalid C++11 braced initialisation of double from long d...
Status: RESOLVED DUPLICATE of bug 55783
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-12-08 08:36 UTC by Marc Mutz
Modified: 2020-04-14 10:14 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marc Mutz 2019-12-08 08:36:49 UTC
The following code:

   // https://godbolt.org/z/tWa2dr
   int main() {
       extern long double ld;
       double d{ld};
   }

is invalid according to [dcl.list.init]3.9 (http://eel.is/c++draft/dcl.init.list#3.9): regardless of a target's actual size for these types, long double -> double is considered a narrowing conversion [dcl.list.init]/7 (http://eel.is/c++draft/dcl.init.list#7.2), and the compiler cannot use the constant expression loophole here.

Clang and MSVC correctly error on this.

Actual behaviour: GCC only warns (-Wnarrowing), even with -pedantic.

Expected behaviour: GCC does not accept this code.

This bug exists in all compiler versions, afaict (4.7.4, 4.8.3, 9.1, trunk).
Comment 1 Jonathan Wakely 2019-12-08 21:10:18 UTC
The standard requires a diagnostic for this, and GCC issues a diagnostic. The behaviour is by design and not a bug.

Use -Werror=narrowing if you want an error.
Comment 2 Jonathan Wakely 2019-12-08 23:28:47 UTC
(In reply to Jonathan Wakely from comment #1)
> The behaviour is by design

And documented, see https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-Wnarrowing

"For C++11 and later standards, narrowing conversions are diagnosed by default, as required by the standard. A narrowing conversion from a constant produces an error, and a narrowing conversion from a non-constant produces a warning, but -Wno-narrowing suppresses the diagnostic. Note that this does not affect the meaning of well-formed code; narrowing conversions are still considered ill-formed in SFINAE contexts."
Comment 3 Marc Mutz 2019-12-09 10:27:58 UTC
Indeed, I didn't check that it actually fails in SFINAE. Sorry for that.

This works:

  // https://godbolt.org/z/EfJmS4
  #include <utility>
  #include <experimental/type_traits>

  template <typename From, typename To>
  using nonnarrowing_test = decltype(To{std::declval<From&>()});

  template <typename From, typename To>
  using is_narrowing = std::negation<std::experimental::is_detected<nonnarrowing_test, From, To>>;

  static_assert(is_narrowing<long double, double>{});
  static_assert(!is_narrowing<double, long double>{});
Comment 4 Marc Mutz 2019-12-09 10:28:26 UTC

*** This bug has been marked as a duplicate of bug 55783 ***
Comment 5 Giuseppe D'Angelo 2020-04-10 14:56:07 UTC
Hi,

This specific bug needs to be reopened: GCC incorrectly accepts long double to double in list initializations, and generates no warnings, on architectures where long double is the same as double.

Testcases:

On ARM: https://godbolt.org/z/SRg3fr
On X86-64 also passing -mlong-double-64: https://godbolt.org/z/GnRkHC

SFINAE contexts are affected as well: https://godbolt.org/z/icMA3k

Clang, MSVC reject the code.
Comment 6 Jonathan Wakely 2020-04-14 10:14:05 UTC
That's a different bug, so thanks for filing it separately (PR 94590).