diff --git a/SOURCES/gcc9-rh1974984.patch b/SOURCES/gcc9-rh1974984.patch new file mode 100644 index 0000000..903cf74 --- /dev/null +++ b/SOURCES/gcc9-rh1974984.patch @@ -0,0 +1,437 @@ +https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=d417b4f5414d9076300ab41974a14424f722688c +https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=75b7b7fdc4597170f24c069ea13aa3e14f37fde7 +https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=8e64d182850560dbedfabb88aac90d4fc6155067 + +diff --git a/gcc/cp/call.c b/gcc/cp/call.c +index 304c01619da..3a15e6e2e47 100644 +--- a/gcc/cp/call.c ++++ b/gcc/cp/call.c +@@ -166,6 +166,8 @@ static tree build_over_call (struct z_candidate *, int, tsubst_flags_t); + /*c_cast_p=*/false, (COMPLAIN)) + static tree convert_like_real (conversion *, tree, tree, int, bool, + bool, tsubst_flags_t); ++static tree convert_like_real_1 (conversion *, tree, tree, int, bool, ++ bool, tsubst_flags_t); + static void op_error (const op_location_t &, enum tree_code, enum tree_code, + tree, tree, tree, bool); + static struct z_candidate *build_user_type_conversion_1 (tree, tree, int, +@@ -6995,6 +6997,39 @@ maybe_inform_about_fndecl_for_bogus_argument_init (tree fn, int argnum) + " initializing argument %P of %qD", argnum, fn); + } + ++/* Wrapper for convert_like_real_1 that handles creating IMPLICIT_CONV_EXPR. */ ++ ++static tree ++convert_like_real (conversion *convs, tree expr, tree fn, int argnum, ++ bool issue_conversion_warnings, ++ bool c_cast_p, tsubst_flags_t complain) ++{ ++ /* Creating &TARGET_EXPR<> in a template breaks when substituting, ++ and creating a CALL_EXPR in a template breaks in finish_call_expr ++ so use an IMPLICIT_CONV_EXPR for this conversion. We would have ++ created such codes e.g. when calling a user-defined conversion ++ function. */ ++ tree conv_expr = NULL_TREE; ++ if (processing_template_decl ++ && convs->kind != ck_identity ++ && (CLASS_TYPE_P (convs->type) || CLASS_TYPE_P (TREE_TYPE (expr)))) ++ { ++ conv_expr = build1 (IMPLICIT_CONV_EXPR, convs->type, expr); ++ if (convs->kind != ck_ref_bind) ++ conv_expr = convert_from_reference (conv_expr); ++ if (!convs->bad_p) ++ return conv_expr; ++ /* Do the normal processing to give the bad_p errors. But we still ++ need to return the IMPLICIT_CONV_EXPR, unless we're returning ++ error_mark_node. */ ++ } ++ expr = convert_like_real_1 (convs, expr, fn, argnum, ++ issue_conversion_warnings, c_cast_p, complain); ++ if (expr == error_mark_node) ++ return error_mark_node; ++ return conv_expr ? conv_expr : expr; ++} ++ + /* Perform the conversions in CONVS on the expression EXPR. FN and + ARGNUM are used for diagnostics. ARGNUM is zero based, -1 + indicates the `this' argument of a method. INNER is nonzero when +@@ -7006,9 +7041,9 @@ maybe_inform_about_fndecl_for_bogus_argument_init (tree fn, int argnum) + conversions to inaccessible bases are permitted. */ + + static tree +-convert_like_real (conversion *convs, tree expr, tree fn, int argnum, +- bool issue_conversion_warnings, +- bool c_cast_p, tsubst_flags_t complain) ++convert_like_real_1 (conversion *convs, tree expr, tree fn, int argnum, ++ bool issue_conversion_warnings, ++ bool c_cast_p, tsubst_flags_t complain) + { + tree totype = convs->type; + diagnostic_t diag_kind; +@@ -7466,6 +7501,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, + expr = convert_bitfield_to_declared_type (expr); + expr = fold_convert (type, expr); + } ++ ++ /* Creating &TARGET_EXPR<> in a template would break when ++ tsubsting the expression, so use an IMPLICIT_CONV_EXPR ++ instead. This can happen even when there's no class ++ involved, e.g., when converting an integer to a reference ++ type. */ ++ if (processing_template_decl) ++ return build1 (IMPLICIT_CONV_EXPR, totype, expr); + expr = build_target_expr_with_type (expr, type, complain); + } + +diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c +index 782f0f6e60f..b7190fb8761 100644 +--- a/gcc/cp/decl.c ++++ b/gcc/cp/decl.c +@@ -9752,13 +9752,12 @@ compute_array_index_type_loc (location_t name_loc, tree name, tree size, + NOP_EXPR with TREE_SIDE_EFFECTS; don't fold in that case. */; + else + { +- size = instantiate_non_dependent_expr_sfinae (size, complain); + size = build_converted_constant_expr (size_type_node, size, complain); + /* Pedantically a constant expression is required here and so + __builtin_is_constant_evaluated () should fold to true if it + is successfully folded into a constant. */ +- size = maybe_constant_value (size, NULL_TREE, +- /*manifestly_const_eval=*/true); ++ size = fold_non_dependent_expr (size, complain, ++ /*manifestly_const_eval=*/true); + + if (!TREE_CONSTANT (size)) + size = origsize; +@@ -16784,10 +16783,8 @@ build_explicit_specifier (tree expr, tsubst_flags_t complain) + /* Wait for instantiation, tsubst_function_decl will handle it. */ + return expr; + +- expr = instantiate_non_dependent_expr_sfinae (expr, complain); +- /* Don't let convert_like_real create more template codes. */ +- processing_template_decl_sentinel s; + expr = build_converted_constant_bool_expr (expr, complain); ++ expr = instantiate_non_dependent_expr_sfinae (expr, complain); + expr = cxx_constant_value (expr); + return expr; + } +diff --git a/gcc/cp/except.c b/gcc/cp/except.c +index 03a9c8e53c7..b113eacacb3 100644 +--- a/gcc/cp/except.c ++++ b/gcc/cp/except.c +@@ -1288,10 +1288,8 @@ build_noexcept_spec (tree expr, tsubst_flags_t complain) + if (TREE_CODE (expr) != DEFERRED_NOEXCEPT + && !value_dependent_expression_p (expr)) + { +- expr = instantiate_non_dependent_expr_sfinae (expr, complain); +- /* Don't let convert_like_real create more template codes. */ +- processing_template_decl_sentinel s; + expr = build_converted_constant_bool_expr (expr, complain); ++ expr = instantiate_non_dependent_expr_sfinae (expr, complain); + expr = cxx_constant_value (expr); + } + if (TREE_CODE (expr) == INTEGER_CST) +diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c +index 612557bb717..710956e5a08 100644 +--- a/gcc/cp/pt.c ++++ b/gcc/cp/pt.c +@@ -6919,19 +6919,6 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) + else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type) + || cxx_dialect >= cxx17) + { +- /* Calling build_converted_constant_expr might create a call to +- a conversion function with a value-dependent argument, which +- could invoke taking the address of a temporary representing +- the result of the conversion. */ +- if (COMPOUND_LITERAL_P (expr) +- && CONSTRUCTOR_IS_DEPENDENT (expr) +- && MAYBE_CLASS_TYPE_P (expr_type) +- && TYPE_HAS_CONVERSION (expr_type)) +- { +- expr = build1 (IMPLICIT_CONV_EXPR, type, expr); +- IMPLICIT_CONV_EXPR_NONTYPE_ARG (expr) = true; +- return expr; +- } + /* C++17: A template-argument for a non-type template-parameter shall + be a converted constant expression (8.20) of the type of the + template-parameter. */ +@@ -6940,6 +6927,11 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) + /* Make sure we return NULL_TREE only if we have really issued + an error, as described above. */ + return (complain & tf_error) ? NULL_TREE : error_mark_node; ++ else if (TREE_CODE (expr) == IMPLICIT_CONV_EXPR) ++ { ++ IMPLICIT_CONV_EXPR_NONTYPE_ARG (expr) = true; ++ return expr; ++ } + expr = maybe_constant_value (expr, NULL_TREE, + /*manifestly_const_eval=*/true); + expr = convert_from_reference (expr); +diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c +index aae5ff24c98..7c5a45c0848 100644 +--- a/gcc/cp/typeck2.c ++++ b/gcc/cp/typeck2.c +@@ -926,7 +926,11 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain, bool const_only) + return ok; + } + +- init = maybe_constant_value (init); ++ /* Even non-dependent expressions can still have template ++ codes like CAST_EXPR, so use *_non_dependent_expr to cope. */ ++ init = fold_non_dependent_expr (init, complain); ++ if (init == error_mark_node) ++ return ok; + + /* If we were asked to only check constants, return early. */ + if (const_only && !TREE_CONSTANT (init)) +diff --git a/gcc/testsuite/g++.dg/conversion/op7.C b/gcc/testsuite/g++.dg/conversion/op7.C +new file mode 100644 +index 00000000000..c6401d109b4 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/conversion/op7.C +@@ -0,0 +1,22 @@ ++// PR c++/94190 - wrong no post-decrement operator error in template. ++ ++struct S { operator long & (); } b; ++ ++template void ++foo () ++{ ++ b--; ++ ++b; ++ --b; ++ b++; ++ !b; ++ ~b; ++ +b; ++ -b; ++} ++ ++void ++bar () ++{ ++ foo<0> (); ++} +diff --git a/gcc/testsuite/g++.dg/conversion/ref4.C b/gcc/testsuite/g++.dg/conversion/ref4.C +new file mode 100644 +index 00000000000..464a4cf6c0f +--- /dev/null ++++ b/gcc/testsuite/g++.dg/conversion/ref4.C +@@ -0,0 +1,22 @@ ++// PR c++/95789 ++// { dg-do compile { target c++11 } } ++ ++struct B { ++ int n; ++}; ++ ++template ++struct A { ++ B& get() const { return f; } // { dg-error "binding reference" } ++ ++ B f; ++}; ++ ++int main() { ++ A a; ++ a.f = {}; ++ ++ a.get().n = 10; ++ if (a.f.n != 0) ++ __builtin_abort(); ++} +diff --git a/gcc/testsuite/g++.dg/conversion/ref5.C b/gcc/testsuite/g++.dg/conversion/ref5.C +new file mode 100644 +index 00000000000..0042acd0670 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/conversion/ref5.C +@@ -0,0 +1,14 @@ ++// PR c++/96104 ++ ++template void fn(T &); ++class E {}; ++struct F { ++ template void mfn(T t) { t, fn(E()); } // { dg-error "cannot bind non-const lvalue reference" } ++}; ++int ++main() ++{ ++ E e; ++ F f; ++ f.mfn(e); ++} +diff --git a/gcc/testsuite/g++.dg/conversion/ref6.C b/gcc/testsuite/g++.dg/conversion/ref6.C +new file mode 100644 +index 00000000000..fc87199053c +--- /dev/null ++++ b/gcc/testsuite/g++.dg/conversion/ref6.C +@@ -0,0 +1,24 @@ ++// PR c++/96179 ++// { dg-do compile { target c++11 } } ++ ++template struct vector ++{ ++ void push_back(T) { } ++}; ++ ++struct dummy{ ++ int a; ++}; ++ ++void Modify_Dummy(dummy &d){ ++ d.a=1; ++} ++ ++template void Templated_Function(){ ++ vector A; ++ A.push_back(Modify_Dummy(dummy{0})); // { dg-error "cannot bind non-const lvalue reference" } ++} ++ ++int main(){ ++ Templated_Function(); ++} +diff --git a/gcc/testsuite/g++.dg/cpp0x/conv-tmpl2.C b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl2.C +new file mode 100644 +index 00000000000..8a505769c3c +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl2.C +@@ -0,0 +1,21 @@ ++// PR c++/92031 - bogus taking address of rvalue error. ++// { dg-do compile { target c++11 } } ++ ++struct x { const int& l; }; ++ ++void a(const x&) {} ++ ++template ++void f() { ++ a(x { 0 }); ++} ++ ++void g() { ++ a(x { 0 }); ++} ++ ++void ++test () ++{ ++ f(); ++} +diff --git a/gcc/testsuite/g++.dg/cpp0x/conv-tmpl3.C b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl3.C +new file mode 100644 +index 00000000000..e2021aa13e1 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl3.C +@@ -0,0 +1,16 @@ ++// PR c++/91465 - ICE with template codes in check_narrowing. ++// { dg-do compile { target c++11 } } ++ ++enum class D { X }; ++enum class S { Z }; ++ ++D foo(S) { return D{}; } ++D foo(double) { return D{}; } ++ ++template ++struct Bar { ++ D baz(S s) ++ { ++ return D{foo(s)}; ++ } ++}; +diff --git a/gcc/testsuite/g++.dg/cpp0x/conv-tmpl4.C b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl4.C +new file mode 100644 +index 00000000000..966a2e1ac9e +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl4.C +@@ -0,0 +1,33 @@ ++// PR c++/93870 - wrong error when converting template non-type arg. ++// { dg-do compile { target c++11 } } ++ ++template struct EnumWrapper ++{ ++ ENUM value; ++ ++ constexpr operator ENUM() const ++ { ++ return value; ++ } ++}; ++ ++enum E : int { V }; ++ ++constexpr EnumWrapper operator ~(E a) ++{ ++ return {E(~int(a))}; ++} ++ ++template struct R ++{ ++ static void Func(); ++}; ++ ++template struct S : R<~X> ++{ ++}; ++ ++void Test() ++{ ++ S::Func(); ++} +diff --git a/gcc/testsuite/g++.dg/cpp0x/conv-tmpl5.C b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl5.C +new file mode 100644 +index 00000000000..c83e6d83ed9 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl5.C +@@ -0,0 +1,13 @@ ++// PR c++/94068 - ICE with template codes in check_narrowing. ++// { dg-do compile { target c++11 } } ++ ++enum class A { A1, A2 }; ++A foo (); ++long foo (int); ++ ++template ++void ++bar () ++{ ++ const auto c{foo ()}; ++} +diff --git a/gcc/testsuite/g++.dg/cpp0x/conv-tmpl6.C b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl6.C +new file mode 100644 +index 00000000000..2df3a6cc129 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/conv-tmpl6.C +@@ -0,0 +1,16 @@ ++// { dg-do compile { target c++11 } } ++ ++struct A ++{ ++ constexpr A(int) { } ++ constexpr operator int() const { return 1; }; ++}; ++ ++template ++struct B ++{ ++ static constexpr A a = A(N); ++ int ar[a]; ++}; ++ ++B b; +diff --git a/gcc/testsuite/g++.dg/cpp1z/conv-tmpl1.C b/gcc/testsuite/g++.dg/cpp1z/conv-tmpl1.C +new file mode 100644 +index 00000000000..5b1205349d0 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp1z/conv-tmpl1.C +@@ -0,0 +1,10 @@ ++// PR c++/91465 - ICE with template codes in check_narrowing. ++// { dg-do compile { target c++17 } } ++ ++enum class E { Z }; ++ ++template ++void foo(F) ++{ ++ E{char(0)}; ++} diff --git a/SPECS/gcc.spec b/SPECS/gcc.spec index ae381af..053531e 100644 --- a/SPECS/gcc.spec +++ b/SPECS/gcc.spec @@ -113,7 +113,7 @@ Summary: GCC version 9 Name: %{?scl_prefix}gcc Version: %{gcc_version} -Release: %{gcc_release}%{?dist} +Release: %{gcc_release}.2%{?dist} # libgcc, libgfortran, libgomp, libstdc++ and crtstuff have # GCC Runtime Exception. License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD @@ -280,6 +280,7 @@ Patch8: gcc9-foffload-default.patch Patch9: gcc9-Wno-format-security.patch Patch10: gcc9-rh1574936.patch Patch11: gcc9-d-shared-libphobos.patch +Patch12: gcc9-rh1974984.patch Patch1000: gcc9-libstdc++-compat.patch Patch1001: gcc9-alt-compat-test.patch @@ -628,6 +629,7 @@ This package contains Leak Sanitizer static runtime library. %patch10 -p0 -b .rh1574936~ %endif %patch11 -p0 -b .d-shared-libphobos~ +%patch12 -p1 -b .rh1974984~ %patch1000 -p0 -b .libstdc++-compat~ %ifarch %{ix86} x86_64 @@ -709,10 +711,11 @@ rm -f gcc/testsuite/go.test/test/chan/goroutines.go # These tests get stuck and don't timeout. -%ifarch ppc64 +%ifarch ppc ppc64 ppc64le rm -f libgomp/testsuite/libgomp.c/target-32.c rm -f libgomp/testsuite/libgomp.c/target-33.c rm -f libgomp/testsuite/libgomp.c/target-34.c +rm -rf libgomp/testsuite/libgomp.oacc* %endif %build @@ -772,7 +775,9 @@ ln -sf libisl.so.15 libisl.so cd ../.. %endif +%ifnarch s390 %{?scl:PATH=%{_bindir}${PATH:+:${PATH}}} +%endif CC=gcc CXX=g++ @@ -1778,6 +1783,11 @@ echo gcc-%{version}-%{release}.%{arch} > $FULLPATH/rpmver %check cd obj-%{gcc_target_platform} +# It just doesn't finish. +%ifarch ppc ppc64 s390x +exit 0 +%endif + %{?scl:PATH=%{_bindir}${PATH:+:${PATH}}} %if 0%{?rhel} <= 8 # Test against the system libstdc++.so.6 + libstdc++_nonshared.a combo @@ -1796,7 +1806,11 @@ cp -a %{gcc_target_platform}/libstdc++-v3/src/.libs/libstdc++_nonshared%{nonshar %endif # run the tests. +%ifnarch ppc ppc64 ppc64le make %{?_smp_mflags} -k check RUNTESTFLAGS="--target_board=unix/'{,-fstack-protector}'" || : +%else +make %{?_smp_mflags} -k check || : +%endif ( LC_ALL=C ../contrib/test_summary -t || : ) 2>&1 | sed -n '/^cat.*EOF/,/^EOF/{/^cat.*EOF/d;/^EOF/d;/^LAST_UPDATED:/d;p;}' > testresults rm -rf gcc/testsuite.prev mv gcc/testsuite{,.prev} @@ -2126,8 +2140,10 @@ fi %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgomp.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgomp.so %if 0%{?rhel} <= 7 +%ifnarch ppc %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgomp_nonshared.a %endif +%endif %if %{build_libitm} %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libitm.spec %endif @@ -2554,6 +2570,12 @@ fi %doc rpm.doc/changelogs/libcc1/ChangeLog* %changelog +* Thu Jun 24 2021 Marek Polacek 9.3.1-2.2 +- backport patches to fix convert_like in template (#1974984) + +* Thu Jun 4 2020 Marek Polacek 9.3.1-2.1 +- bump for rebuild on ppc/s390 + * Wed Apr 8 2020 Marek Polacek 9.3.1-2 - update from Fedora gcc-9.3.1-2