Created attachment 48762 [details] Preprocessed file without iostream Hello, I've recently updated from gcc 9.3.0 to 10.1.0 and found some unexpected behaviour when trying to compile this code: #include <iostream> struct B { int n; }; template <typename T> struct A { B& get() const { return f; } B f; }; int main() { A<int> a; a.f = {}; a.get().n = 10; std::cout << a.f.n << std::endl; return 0; } As I understand this code shouldn't compile with error binding reference of type ‘B&’ to ‘const B’ discards qualifiers but this code compiles successfully. What is more interesting is that this code will stop compiling if I remove template or if I use POD type like int. Neither gcc 9.3.0 compiles this code nor clang does. GCC info: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --with-isl --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-install-libiberty --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-libunwind-exceptions --disable-werror gdc_include_dir=/usr/include/dlang/gdc Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 10.1.0 (GCC) Compiling with -Wall -Wextra yields no output warnings or errors. I've attached preprocessed file without iostream.
struct B { int n; }; template <typename T> struct A { B& get() const { return f; } B f; }; int main() { A<int> a; a.f = {}; a.get().n = 10; if (a.f.n != 0) __builtin_abort(); } Started with r10-7094 c++: Readd [LR]ROTATE_EXPR support to constexpr.c [PR94067] Since r10-6527-gaaa26bf496a646778ac861aed124d960b5bf549f fold_for_warn will perform maybe_constant_value even on some cp_fold produced trees and so can include rotate exprs which were removed last fall from constexpr.c 2020-03-09 Jakub Jelinek <jakub@redhat.com> PR c++/94067 Revert 2019-10-11 Paolo Carlini <paolo.carlini@oracle.com> * constexpr.c (cxx_eval_constant_expression): Do not handle RROTATE_EXPR and LROTATE_EXPR. * g++.dg/warn/Wconversion-pr94067.C: New test.
This actually started with r10-7096-gd417b4f5414d9076300ab41974a14424f722688c so mine.
*** Bug 96096 has been marked as a duplicate of this bug. ***
*** Bug 96104 has been marked as a duplicate of this bug. ***
Another test: // PR c++/96104 template <typename T> void fn(T &); class E {}; struct F { template <typename T> void mfn(T t) { t, fn(E()); } // { dg-error "cannot bind non-const lvalue reference" } }; int main() { E e; F f; f.mfn(e); }
*** Bug 96179 has been marked as a duplicate of this bug. ***
// PR c++/96179 template<typename T> struct vector { void push_back(T) { } }; struct dummy{ int a; }; void Modify_Dummy(dummy &d){ d.a=1; } template <bool bla=true> void Templated_Function(){ vector<dummy> A; A.push_back(Modify_Dummy(dummy{0})); } int main(){ Templated_Function(); }
The master branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>: https://gcc.gnu.org/g:8e64d182850560dbedfabb88aac90d4fc6155067 commit r11-2097-g8e64d182850560dbedfabb88aac90d4fc6155067 Author: Marek Polacek <polacek@redhat.com> Date: Mon Jun 22 21:26:49 2020 -0400 c++: Make convert_like complain about bad ck_ref_bind again [PR95789] convert_like issues errors about bad_p conversions at the beginning of the function, but in the ck_ref_bind case, it only issues them after we've called convert_like on the next conversion. This doesn't work as expected since r10-7096 because when we see a conversion from/to class type in a template, we return early, thereby missing the error, and a bad_p conversion goes by undetected. That made the attached test to compile even though it should not. I had thought that I could just move the ck_ref_bind/bad_p errors above to the rest of them, but that regressed diagnostics because expr then wasn't converted yet by the nested convert_like_real call. So, for bad_p conversions, do the normal processing, but still return the IMPLICIT_CONV_EXPR to avoid introducing trees that the template processing can't handle well. This I achieved by adding a wrapper function. gcc/cp/ChangeLog: PR c++/95789 PR c++/96104 PR c++/96179 * call.c (convert_like_real_1): Renamed from convert_like_real. (convert_like_real): New wrapper for convert_like_real_1. gcc/testsuite/ChangeLog: PR c++/95789 PR c++/96104 PR c++/96179 * g++.dg/conversion/ref4.C: New test. * g++.dg/conversion/ref5.C: New test. * g++.dg/conversion/ref6.C: New test.
The releases/gcc-10 branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>: https://gcc.gnu.org/g:315b87f63bcde4c881e9963c39d57258da08ccb5 commit r10-8497-g315b87f63bcde4c881e9963c39d57258da08ccb5 Author: Marek Polacek <polacek@redhat.com> Date: Mon Jun 22 21:26:49 2020 -0400 c++: Make convert_like complain about bad ck_ref_bind again [PR95789] convert_like issues errors about bad_p conversions at the beginning of the function, but in the ck_ref_bind case, it only issues them after we've called convert_like on the next conversion. This doesn't work as expected since r10-7096 because when we see a conversion from/to class type in a template, we return early, thereby missing the error, and a bad_p conversion goes by undetected. That made the attached test to compile even though it should not. I had thought that I could just move the ck_ref_bind/bad_p errors above to the rest of them, but that regressed diagnostics because expr then wasn't converted yet by the nested convert_like_real call. So, for bad_p conversions, do the normal processing, but still return the IMPLICIT_CONV_EXPR to avoid introducing trees that the template processing can't handle well. This I achieved by adding a wrapper function. gcc/cp/ChangeLog: PR c++/95789 PR c++/96104 PR c++/96179 * call.c (convert_like_real_1): Renamed from convert_like_real. (convert_like_real): New wrapper for convert_like_real_1. gcc/testsuite/ChangeLog: PR c++/95789 PR c++/96104 PR c++/96179 * g++.dg/conversion/ref4.C: New test. * g++.dg/conversion/ref5.C: New test. * g++.dg/conversion/ref6.C: New test. (cherry picked from commit 8e64d182850560dbedfabb88aac90d4fc6155067)
Fixed for 11/10.2.