Summary: | [8/9 Regression] gcc internal error since 8x on warning write-strings | ||
---|---|---|---|
Product: | gcc | Reporter: | Mikołaj <mikolajmm> |
Component: | c++ | Assignee: | Patrick Palka <ppalka> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | jakub, jason, nickhuang99, ppalka, webrown.cpp |
Priority: | P2 | Keywords: | ice-on-valid-code |
Version: | 9.2.0 | ||
Target Milestone: | 8.5 | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2019-10-07 00:00:00 | |
Attachments: | internal compiler error with casting const char* to char* |
Description
Mikołaj
2019-10-07 08:08:04 UTC
template <typename T = char[3]> void foo(const T t = "; ") { } int main() { foo (); } $ ./cc1plus -quiet 92010.C 92010.C: In function ‘int main()’: 92010.C:8:8: internal compiler error: in tsubst_default_argument, at cp/pt.c:13356 8 | foo (); | ^ 0xbc86f1 tsubst_default_argument(tree_node*, int, tree_node*, tree_node*, int) /home/mpolacek/src/gcc/gcc/cp/pt.c:13356 0x938263 convert_default_arg(tree_node*, tree_node*, tree_node*, int, int) /home/mpolacek/src/gcc/gcc/cp/call.c:8044 0x93b170 build_over_call /home/mpolacek/src/gcc/gcc/cp/call.c:8751 0x92b2ca build_new_function_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, int) /home/mpolacek/src/gcc/gcc/cp/call.c:4587 0xc3b4ce finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int) /home/mpolacek/src/gcc/gcc/cp/semantics.c:2671 0xb2cdd1 cp_parser_postfix_expression /home/mpolacek/src/gcc/gcc/cp/parser.c:7427 0xb2f71e cp_parser_unary_expression /home/mpolacek/src/gcc/gcc/cp/parser.c:8525 0xb30b88 cp_parser_cast_expression /home/mpolacek/src/gcc/gcc/cp/parser.c:9416 0xb30c75 cp_parser_binary_expression /home/mpolacek/src/gcc/gcc/cp/parser.c:9519 0xb31aba cp_parser_assignment_expression /home/mpolacek/src/gcc/gcc/cp/parser.c:9824 0xb31e71 cp_parser_expression /home/mpolacek/src/gcc/gcc/cp/parser.c:9992 0xb35acb cp_parser_expression_statement /home/mpolacek/src/gcc/gcc/cp/parser.c:11642 0xb35398 cp_parser_statement /home/mpolacek/src/gcc/gcc/cp/parser.c:11438 0xb3603f cp_parser_statement_seq_opt /home/mpolacek/src/gcc/gcc/cp/parser.c:11789 0xb35f23 cp_parser_compound_statement /home/mpolacek/src/gcc/gcc/cp/parser.c:11739 0xb4bcd6 cp_parser_function_body /home/mpolacek/src/gcc/gcc/cp/parser.c:22981 0xb4bffa cp_parser_ctor_initializer_opt_and_function_body /home/mpolacek/src/gcc/gcc/cp/parser.c:23032 0xb57904 cp_parser_function_definition_after_declarator /home/mpolacek/src/gcc/gcc/cp/parser.c:28880 0xb5772b cp_parser_function_definition_from_specifiers_and_declarator /home/mpolacek/src/gcc/gcc/cp/parser.c:28796 0xb4700e cp_parser_init_declarator /home/mpolacek/src/gcc/gcc/cp/parser.c:20596 GCC 8.4.0 has been released, adjusting target milestone. Looking into it. The ICE seems to be revealing a latent issue: In the following example (which GCC accepts), according to the static_assert labelled (1), the type of t is const int*, but according to the static_assert labelled (2), the type of t is int *const. template <typename T> void foo(const T t) { static_assert(__is_same(decltype(t), const int*)); // (1) } static_assert(__is_same(decltype(foo<int[]>), void(int *))); // (2) int main() { foo<int[]>(nullptr); } (In reply to Patrick Palka from comment #5) > The ICE seems to be revealing a latent issue: In the following example > (which GCC accepts), according to the static_assert labelled (1), the type > of t is const int*, but according to the static_assert labelled (2), the > type of t is int *const. > > > > template <typename T> > void foo(const T t) > { > static_assert(__is_same(decltype(t), const int*)); // (1) > } > > static_assert(__is_same(decltype(foo<int[]>), void(int *))); // (2) > > int > main() > { > foo<int[]>(nullptr); > } So the question becomes, what should the type of t be here? According to https://eel.is/c++draft/temp#deduct-3: "A top-level qualifier in a function parameter declaration does not affect the function type but still affects the type of the function parameter variable within the function." The above suggests that the type of foo<int[]> should be the same regardless of where the parameter t is const-qualified. Going by this then, it appears that the static_assert (2) is right and (1) is wrong. Can anyone confirm? (On the other hand, Clang thinks (1) is right and (2) is wrong.) (In reply to Patrick Palka from comment #6) > (In reply to Patrick Palka from comment #5) > > The ICE seems to be revealing a latent issue: In the following example > > (which GCC accepts), according to the static_assert labelled (1), the type > > of t is const int*, but according to the static_assert labelled (2), the > > type of t is int *const. > > > > > > > > template <typename T> > > void foo(const T t) > > { > > static_assert(__is_same(decltype(t), const int*)); // (1) > > } > > > > static_assert(__is_same(decltype(foo<int[]>), void(int *))); // (2) > > > > int > > main() > > { > > foo<int[]>(nullptr); > > } > > So the question becomes, what should the type of t be here? According to > https://eel.is/c++draft/temp#deduct-3: > > "A top-level qualifier in a function parameter declaration does not affect > the function type but still affects the type of the function parameter > variable within the function." > > The above suggests that the type of foo<int[]> should be the same regardless > of where the parameter t is const-qualified. Going by this then, it appears > that the static_assert (2) is right and (1) is wrong. Can anyone confirm? > > (On the other hand, Clang thinks (1) is right and (2) is wrong.) So I think the quoted wording from [temp.deduct]/3 applies to function parameter types _after_ substitution. So this doesn't definitively tell us anything about the type of t. I think the answer lies in [basic.type.qualifier]/3, which says: "Cv-qualifiers applied to an array type attach to the underlying element type, so the notation “cv T”, where T is an array type, refers to an array whose elements are so-qualified ([dcl.array]" So the type const T after substituting T=int[] is precisely const int[], which as a parameter type then decays to const int* according to [dcl.fct]/5. So it seems that the static_assert (1) is right, and (2) is wrong. The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>: https://gcc.gnu.org/g:12f55e030ed068d5c7b14c65a74d102db925dab2 commit r10-7622-g12f55e030ed068d5c7b14c65a74d102db925dab2 Author: Patrick Palka <ppalka@redhat.com> Date: Mon Mar 30 19:55:03 2020 -0400 c++: Function type and parameter type disagreements [PR92010] This resolves parts of Core issues 1001/1322 by rebuilding the function type of an instantiated function template in terms of its formal parameter types whenever the original function type and formal parameter types disagree about the type of a parameter after substitution. gcc/cp/ChangeLog: Core issues 1001 and 1322 PR c++/92010 * pt.c (rebuild_function_or_method_type): Split function out from ... (tsubst_function_type): ... here. (maybe_rebuild_function_decl_type): New function. (tsubst_function_decl): Use it. gcc/testsuite/ChangeLog: Core issues 1001 and 1322 PR c++/92010 * g++.dg/cpp2a/lambda-uneval11.c: New test. * g++.dg/template/array33.C: New test. * g++.dg/template/array34.C: New test. * g++.dg/template/defarg22.C: New test. Fixed on GCC 10 so far. The thread https://gcc.gnu.org/pipermail/gcc-patches/2020-March/542487.html which continues at https://gcc.gnu.org/pipermail/gcc-patches/2020-April/543094.html discusses this PR and the ultimate fix. This fix seems too risky to backport. The testcase g++.dg/cpp2a/lambda-uneval11.C still suffers a segment fault if run by compiler cc1plus with latest code. And gdb shows that global var "current_function_decl" is set to 0 when crashed. Should we reopen this bug? ./install/libexec/gcc/x86_64-unknown-linux-gnu/12.0.0/cc1plus -std=c++20 gcc-clone/gcc/testsuite/g++.dg/cpp2a/lambda-uneval11.C <lambda()> void spam(decltype (<lambda>) (*)[sizeof (T)]) void foo() <lambda()> static constexpr void<lambda()>::_FUN() constexpr<lambda()>::operator void (*)()() const <lambda()> static constexpr void<lambda()>::_FUN() constexpr<lambda()>::operator void (*)()() const <lambda()> static constexpr void<lambda()>::_FUN() constexpr<lambda()>::operator void (*)()() const <lambda()> static constexpr void<lambda()>::_FUN() constexpr<lambda()>::operator void (*)()() const constexpr<lambda()>::operator void (*)()() const <lambda()> static constexpr void<lambda()>::_FUN() constexpr<lambda()>::operator void (*)()() const gcc-clone/gcc/testsuite/g++.dg/cpp2a/lambda-uneval11.C: In instantiation of ‘constexpr<lambda()>::operator void (*)()() const’: gcc-clone/gcc/testsuite/g++.dg/cpp2a/lambda-uneval11.C:9:12: required from here gcc-clone/gcc/testsuite/g++.dg/cpp2a/lambda-uneval11.C:4:25: internal compiler error: Segmentation fault 4 | template <class T> void spam(decltype([]{}) (*s)[sizeof(T)] = nullptr) | ^~~~ Please submit a full bug report, with preprocessed source if appropriate. See <https://gcc.gnu.org/bugs/> for instructions. (In reply to qingzhe huang from comment #11) > The testcase g++.dg/cpp2a/lambda-uneval11.C still suffers a segment fault if > run by compiler cc1plus with latest code. Hmm, I can't reproduce that on latest trunk. Is your working tree clean? (In reply to Patrick Palka from comment #12) > (In reply to qingzhe huang from comment #11) > > The testcase g++.dg/cpp2a/lambda-uneval11.C still suffers a segment fault if > > run by compiler cc1plus with latest code. > > Hmm, I can't reproduce that on latest trunk. Is your working tree clean? I tested in both 10.2.x and 11.2.x and even latest 12.x with yesterday pull. It won't show anything when compiling with driver, i.e. g++, but if you run "cc1plus", it will crash. For example, ${GCC_INSTALL}/libexec/gcc/x86_64-unknown-linux-gnu/11.2.0/cc1plus -std=c++20 ./lambda-uneval11.C Thank you (In reply to qingzhe huang from comment #13) > (In reply to Patrick Palka from comment #12) > > (In reply to qingzhe huang from comment #11) > > > The testcase g++.dg/cpp2a/lambda-uneval11.C still suffers a segment fault if > > > run by compiler cc1plus with latest code. > > > > Hmm, I can't reproduce that on latest trunk. Is your working tree clean? > > I tested in both 10.2.x and 11.2.x and even latest 12.x with yesterday pull. > It won't show anything when compiling with driver, i.e. g++, but if you run > "cc1plus", it will crash. For example, > ${GCC_INSTALL}/libexec/gcc/x86_64-unknown-linux-gnu/11.2.0/cc1plus > -std=c++20 ./lambda-uneval11.C > > Thank you Ah yeah, I can reproduce the crash when invoking cc1plus directly and also when passing -Q to the driver. Might be better to open a separate PR for this as it seems to be a latent bug. >>Might be better to open a separate PR for this as it seems to be a latent bug. thanks, I will file a new bug. From: ppalka at gcc dot gnu.org <gcc-bugzilla@gcc.gnu.org> Sent: October 5, 2021 5:05 PM To: nickhuang99@hotmail.com <nickhuang99@hotmail.com> Subject: [Bug c++/92010] [8/9 Regression] gcc internal error since 8x on warning write-strings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92010 --- Comment #14 from Patrick Palka <ppalka at gcc dot gnu.org> --- (In reply to qingzhe huang from comment #13) > (In reply to Patrick Palka from comment #12) > > (In reply to qingzhe huang from comment #11) > > > The testcase g++.dg/cpp2a/lambda-uneval11.C still suffers a segment fault if > > > run by compiler cc1plus with latest code. > > > > Hmm, I can't reproduce that on latest trunk. Is your working tree clean? > > I tested in both 10.2.x and 11.2.x and even latest 12.x with yesterday pull. > It won't show anything when compiling with driver, i.e. g++, but if you run > "cc1plus", it will crash. For example, > ${GCC_INSTALL}/libexec/gcc/x86_64-unknown-linux-gnu/11.2.0/cc1plus > -std=c++20 ./lambda-uneval11.C > > Thank you Ah yeah, I can reproduce the crash when invoking cc1plus directly and also when passing -Q to the driver. Might be better to open a separate PR for this as it seems to be a latent bug. > Ah yeah, I can reproduce the crash when invoking cc1plus directly and also > when > passing -Q to the driver. Might be better to open a separate PR for this as > it > seems to be a latent bug. just opened a new bug: pr102624 |