Summary: | [10/11/12 Regression] segfault from static_assert with user-defined string suffix argument | ||
---|---|---|---|
Product: | gcc | Reporter: | Jack Applin <Jack> |
Component: | c++ | Assignee: | Marek Polacek <mpolacek> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | marxin, mpolacek, stevenxia990430, webrown.cpp |
Priority: | P2 | Keywords: | diagnostic, ice-on-invalid-code |
Version: | 11.2.0 | ||
Target Milestone: | 10.5 | ||
Host: | Target: | ||
Build: | Known to work: | 5.5.0 | |
Known to fail: | 6.1.0 | Last reconfirmed: | 2022-04-19 00:00:00 |
Attachments: | preprocessed source to reproduce the error |
Is it really a valid code since clang rejects it? $ clang++ pr105300.C -c pr105300.C:2:27: error: string literal with user-defined suffix cannot be used here static_assert(false, "foo"_x); ^ 1 error generated. MSVC produces a decent error message: <source>(2): error C3690: expected a string literal, but found a user-defined string literal instead Note best definition of the operator is just: void operator""_x(const char *, decltype(sizeof(0))); static_assert(false, "foo"_x); Oh we started to ICE between GCC 5 and 6. Most likely when we started to print out the message too. Something like: diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 7c5f90b5127..185e0ac53f7 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -11203,6 +11203,13 @@ finish_static_assert (tree condition, tree message, location_t location, if (check_for_bare_parameter_packs (condition)) condition = error_mark_node; + if (TREE_CODE (message) != STRING_CST) + { + location_t mloc = cp_expr_loc_or_loc (message, location); + error_at (mloc, "user defined suffix not expected here"); + return; + } + if (instantiation_dependent_expression_p (condition)) { /* We're in a template; build a STATIC_ASSERT and put it in Should fix this I think .... We also crash on asm (""_x); but not extern ""_x { void g(); } A more complete test: // PR c++/105300 void operator""_x(const char *, decltype(sizeof(0))); static_assert(false, "foo"_x); extern ""_x { void g(); } void lol () { asm (""_x); } The trunk branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>: https://gcc.gnu.org/g:9f353b0c1dc9385ba8b8a64b65d66d5452383c11 commit r13-5390-g9f353b0c1dc9385ba8b8a64b65d66d5452383c11 Author: Marek Polacek <polacek@redhat.com> Date: Fri Nov 11 17:59:30 2022 -0500 c++: Reject UDLs in certain contexts [PR105300] In this PR, we are crashing because we've encountered a UDL where a string-literal is expected. This patch makes the parser reject string and character UDLs in all places where the grammar requires a string-literal and not a user-defined-string-literal. I've introduced two new wrappers; the existing cp_parser_string_literal was renamed to cp_parser_string_literal_common and should not be called directly. finish_userdef_string_literal is renamed from cp_parser_userdef_string_literal. PR c++/105300 gcc/c-family/ChangeLog: * c-pragma.cc (handle_pragma_message): Warn for CPP_STRING_USERDEF. gcc/cp/ChangeLog: * parser.cc: Remove unnecessary forward declarations. (cp_parser_string_literal): New wrapper. (cp_parser_string_literal_common): Renamed from cp_parser_string_literal. Add a bool parameter. Give an error when UDLs are not permitted. (cp_parser_userdef_string_literal): New wrapper. (finish_userdef_string_literal): Renamed from cp_parser_userdef_string_literal. (cp_parser_primary_expression): Call cp_parser_userdef_string_literal instead of cp_parser_string_literal. (cp_parser_linkage_specification): Move a variable declaration closer to its first use. (cp_parser_static_assert): Likewise. (cp_parser_operator): Call cp_parser_userdef_string_literal instead of cp_parser_string_literal. (cp_parser_asm_definition): Move a variable declaration closer to its first use. (cp_parser_asm_specification_opt): Move variable declarations closer to their first use. (cp_parser_asm_operand_list): Likewise. (cp_parser_asm_clobber_list): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/udlit-error1.C: New test. Fixed for GCC 13. I don't think I want to backport the patch. *** Bug 109459 has been marked as a duplicate of this bug. *** |
Created attachment 52824 [details] preprocessed source to reproduce the error $ cat bad.ii void operator""_x(const char *, unsigned long); static_assert(false, "foo"_x); $ g++ bad.ii bad.ii:2:15: internal compiler error: Segmentation fault 2 | static_assert(false, "foo"_x); | ^~~~~ 0xb0c67e crash_signal ../../src/gcc/toplev.c:327 0x7fb38e75951f ??? ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0 0x7dd197 finish_static_assert(tree_node*, tree_node*, unsigned int, bool, bool) ../../src/gcc/cp/semantics.c:10134 0x15089c8 cp_parser_static_assert ../../src/gcc/cp/parser.c:15464 0xf9ed91 cp_parser_declaration ../../src/gcc/cp/parser.c:14164 0x149bba3 cp_parser_toplevel_declaration ../../src/gcc/cp/parser.c:14193 0x149bba3 cp_parser_translation_unit ../../src/gcc/cp/parser.c:4942 0x149bba3 c_parse_file() ../../src/gcc/cp/parser.c:45326 0x1489a5e c_common_parse_file() ../../src/gcc/c-family/c-opts.c:1218 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <file:///usr/share/doc/gcc-11/README.Bugs> for instructions. $ g++ --version g++ (Ubuntu 11.2.0-7ubuntu2) 11.2.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.