Bug 105300 - [10/11/12 Regression] segfault from static_assert with user-defined string suffix argument
Summary: [10/11/12 Regression] segfault from static_assert with user-defined string su...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.2.0
: P2 normal
Target Milestone: 10.5
Assignee: Marek Polacek
URL:
Keywords: diagnostic, ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2022-04-18 03:51 UTC by Jack Applin
Modified: 2023-01-26 15:21 UTC (History)
3 users (show)

See Also:
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 (81 bytes, text/plain)
2022-04-18 03:51 UTC, Jack Applin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jack Applin 2022-04-18 03:51:30 UTC
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.
Comment 1 Martin Liška 2022-04-19 14:11:24 UTC
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.
Comment 2 Andrew Pinski 2022-11-03 00:21:54 UTC
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.
Comment 3 Andrew Pinski 2022-11-03 00:32:40 UTC
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 ....
Comment 4 Marek Polacek 2022-11-11 20:39:42 UTC
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);
}
Comment 5 CVS Commits 2023-01-26 15:08:46 UTC
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.
Comment 6 Marek Polacek 2023-01-26 15:21:50 UTC
Fixed for GCC 13.  I don't think I want to backport the patch.