Bug 92517 - [10 Regression] ICE on incorrect syntax involving requires and decltype
Summary: [10 Regression] ICE on incorrect syntax involving requires and decltype
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.0
: P1 normal
Target Milestone: 10.0
Assignee: Jason Merrill
URL:
Keywords: ice-on-invalid-code
: 92837 93629 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-11-14 20:18 UTC by Bence Szabó
Modified: 2021-08-08 07:49 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-01-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Bence Szabó 2019-11-14 20:18:40 UTC
Naively adding decltype with wrong syntax in order fix "expected a type, got 'I'" results in segfault with following code:

template <typename T>
concept C = true;

template<int I>
requires C decltype<I>
void f() {}

flags: -std=c++2a -fconcepts

gcc 9.2 produces correct error message
Comment 1 Bence Szabó 2019-11-16 08:01:12 UTC
started with r276764
Comment 2 Jakub Jelinek 2020-01-16 17:18:51 UTC
This happens during tentative parsing, so no errors are reported for decltype not being followed by ( auto ) tokens and we segfault on trying to dereference NULL open_paren to get open_paren->location.

The following patch avoids the ICE, on this testcase then reports:
--- gcc/cp/parser.c.jj	2020-01-16 12:15:47.211552009 +0100
+++ gcc/cp/parser.c	2020-01-16 17:41:39.322353708 +0100
@@ -18237,10 +18237,15 @@ cp_parser_placeholder_type_specifier (cp
 	  placeholder = cp_lexer_consume_token (parser->lexer);
 	  open_paren = cp_parser_require (parser, CPP_OPEN_PAREN,
 					  RT_OPEN_PAREN);
-	  cp_parser_require_keyword (parser, RID_AUTO, RT_AUTO);
+	  if (!open_paren)
+	    return error_mark_node;
+	  if (!cp_parser_require_keyword (parser, RID_AUTO, RT_AUTO))
+	    return error_mark_node;
           close_paren = cp_parser_require (parser, CPP_CLOSE_PAREN,
 					   RT_CLOSE_PAREN,
 					   open_paren->location);
+	  if (!close_paren)
+	    return error_mark_node;
 	}
     }
 
pr92517.C:5:10: error: ‘C’ does not name a type
    5 | requires C decltype<I>
      |          ^

Is that what we want, or do we want to emit an error even during tentative parsing, or make the whole function deal with NULL open_paren and/or close_paren and let the caller's do something?  For open_paren it would be a matter of open_paren ? open_paren->location : UNKNOWN_LOCATION, for close_paren there is a single spot where we could use placeholder->location if close_paren is NULL.
Comment 3 GCC Commits 2020-02-07 13:55:15 UTC
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:82aee6dd61e2a5b4e4b124f896c8403169688f41

commit r10-6506-g82aee6dd61e2a5b4e4b124f896c8403169688f41
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Feb 6 16:14:19 2020 -0500

    c++: Fix ICE on nonsense requires-clause.
    
    Here we were swallowing all the syntax errors by parsing tentatively, and
    returning error_mark_node without ever actually giving an error.  Fixed by
    using save_tokens/rollback_tokens instead.
    
    	PR c++/92517
    	* parser.c (cp_parser_constraint_primary_expression): Do the main
    	parse non-tentatively.
Comment 4 Jason Merrill 2020-02-07 15:01:11 UTC
Fixed.
Comment 5 Jonathan Wakely 2020-02-07 20:31:01 UTC
*** Bug 93629 has been marked as a duplicate of this bug. ***
Comment 6 Andrew Pinski 2021-08-08 07:49:47 UTC
*** Bug 92837 has been marked as a duplicate of this bug. ***