Bug 68087 - [5/6 Regression] ICE with constexpr in array with negative index
Summary: [5/6 Regression] ICE with constexpr in array with negative index
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.0
: P2 normal
Target Milestone: 5.3
Assignee: Paolo Carlini
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2015-10-25 09:46 UTC by Roger Ferrer Ibanez
Modified: 2016-03-02 16:27 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-10-25 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Roger Ferrer Ibanez 2015-10-25 09:46:17 UTC
Hi,

GCC 6.0.0 20151025 and 5.2 crash with an ICE with the following code:

-- ice.cc
constexpr char c[] = "hello";
constexpr const char *p = c;

void f()
{
    static_assert(*(p-1) == 'h', "");
}
-- end of ice.cc

$ g++ --version
g++ (GCC) 6.0.0 20151025 (experimental)
$ g++ -std=c++11 -c ice.cc

ice.cc: In function ‘void f()’:
ice.cc:6:37: internal compiler error: in tree_to_shwi, at tree.c:7304
     static_assert(*(p-1) == 'h', "");
                                     ^
0xf2fec2 tree_to_shwi(tree_node const*)
	../../gcc-git/gcc/tree.c:7304
0x7fc084 cxx_eval_array_reference
	../../gcc-git/gcc/cp/constexpr.c:1785
0x7fc084 cxx_eval_constant_expression
	../../gcc-git/gcc/cp/constexpr.c:3485
0x7fb18c cxx_eval_indirect_ref
	../../gcc-git/gcc/cp/constexpr.c:2588
0x7fb18c cxx_eval_constant_expression
	../../gcc-git/gcc/cp/constexpr.c:3340
0x7fe63e cxx_eval_binary_expression
	../../gcc-git/gcc/cp/constexpr.c:1601
0x7fa994 cxx_eval_constant_expression
	../../gcc-git/gcc/cp/constexpr.c:3462
0x7fff0b cxx_eval_outermost_constant_expr
	../../gcc-git/gcc/cp/constexpr.c:3746
0x801980 maybe_constant_value(tree_node*, tree_node*)
	../../gcc-git/gcc/cp/constexpr.c:3859
0x772f15 finish_static_assert(tree_node*, tree_node*, unsigned int, bool)
	../../gcc-git/gcc/cp/semantics.c:8291
0x6f47a2 cp_parser_static_assert
	../../gcc-git/gcc/cp/parser.c:12662
0x70b099 cp_parser_block_declaration
	../../gcc-git/gcc/cp/parser.c:11880
0x70bed1 cp_parser_declaration_statement
	../../gcc-git/gcc/cp/parser.c:11496
0x70804a cp_parser_statement
	../../gcc-git/gcc/cp/parser.c:10162
0x708971 cp_parser_statement_seq_opt
	../../gcc-git/gcc/cp/parser.c:10440
0x708a73 cp_parser_compound_statement
	../../gcc-git/gcc/cp/parser.c:10394
0x708c00 cp_parser_function_body
	../../gcc-git/gcc/cp/parser.c:20216
0x708c00 cp_parser_ctor_initializer_opt_and_function_body
	../../gcc-git/gcc/cp/parser.c:20252
0x709929 cp_parser_function_definition_after_declarator
	../../gcc-git/gcc/cp/parser.c:24856
0x70a82b cp_parser_function_definition_from_specifiers_and_declarator
	../../gcc-git/gcc/cp/parser.c:24768
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.


GCC 5.1 and earlier emit a diagnostic instead:

$ g++-5.1 -std=c++11 -c ice.cc
ice.cc: In function ‘void f()’:
ice.cc:6:5: error: non-constant condition for static assertion
     static_assert(*(p-1) == 'h', "");
     ^
ice.cc:6:5: error: array subscript out of bound

Kind regards,
Comment 1 Markus Trippelsdorf 2015-10-25 10:00:11 UTC
Confirmed.
Comment 2 Markus Trippelsdorf 2015-10-25 11:33:13 UTC
Perhaps:

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index ebca411..0828a90 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1782,8 +1782,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
       gcc_unreachable ();
     }
 
-  i = tree_to_shwi (index);
-  if (i < 0)
+  if (!tree_fits_shwi_p (index) || tree_to_shwi (index) < 0)
     {
       if (!ctx->quiet)
        error ("negative array subscript");
@@ -1792,6 +1791,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
     }
 
   bool found;
+  i = tree_to_shwi (index);
   if (TREE_CODE (ary) == CONSTRUCTOR)
     {
       HOST_WIDE_INT ix = find_array_ctor_elt (ary, index);
Comment 3 Paolo Carlini 2015-11-25 13:16:39 UTC
Testing variants of Markus' suggestion.
Comment 4 paolo@gcc.gnu.org 2015-11-25 16:40:48 UTC
Author: paolo
Date: Wed Nov 25 16:40:16 2015
New Revision: 230886

URL: https://gcc.gnu.org/viewcvs?rev=230886&root=gcc&view=rev
Log:
/cp
2015-11-25  Markus Trippelsdorf  <markus@trippelsdorf.de>
	    Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/68087
	* constexpr.c (cxx_eval_array_reference): Use tree_fits_shwi_p before
	tree_to_shwi to avoid ICEs.

/testsuite
2015-11-25  Markus Trippelsdorf  <markus@trippelsdorf.de>
	    Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/68087
	* g++.dg/cpp0x/constexpr-array13.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-array13.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/constexpr.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 paolo@gcc.gnu.org 2015-11-25 16:42:50 UTC
Author: paolo
Date: Wed Nov 25 16:42:18 2015
New Revision: 230887

URL: https://gcc.gnu.org/viewcvs?rev=230887&root=gcc&view=rev
Log:
/cp
2015-11-25  Markus Trippelsdorf  <markus@trippelsdorf.de>
	    Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/68087
	* constexpr.c (cxx_eval_array_reference): Use tree_fits_shwi_p before
	tree_to_shwi to avoid ICEs.

/testsuite
2015-11-25  Markus Trippelsdorf  <markus@trippelsdorf.de>
	    Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/68087
	* g++.dg/cpp0x/constexpr-array13.C: New.

Added:
    branches/gcc-5-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-array13.C
Modified:
    branches/gcc-5-branch/gcc/cp/ChangeLog
    branches/gcc-5-branch/gcc/cp/constexpr.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
Comment 6 Markus Trippelsdorf 2015-11-25 16:44:32 UTC
Fixed. Thanks for handling this, Paolo.
Comment 7 Jakub Jelinek 2015-11-25 19:42:08 UTC
The testcase fails on i686-linux:
/home/jakub/src/gcc/gcc/testsuite/g++.dg/cpp0x/constexpr-array13.C:6:26: error: array subscript out of bound
compiler exited with status 1
output is:
/home/jakub/src/gcc/gcc/testsuite/g++.dg/cpp0x/constexpr-array13.C:6:26: error: array subscript out of bound

FAIL: g++.dg/cpp0x/constexpr-array13.C  -std=c++11  (test for errors, line 6)
FAIL: g++.dg/cpp0x/constexpr-array13.C  -std=c++11 (test for excess errors)
Excess errors:
/home/jakub/src/gcc/gcc/testsuite/g++.dg/cpp0x/constexpr-array13.C:6:26: error: array subscript out of bound
Comment 8 Paolo Carlini 2015-11-25 20:38:16 UTC
I see, thanks. I'm going to trivially tweak the dg-error.
Comment 9 Jason Merrill 2016-03-02 02:46:50 UTC
Author: jason
Date: Wed Mar  2 02:45:45 2016
New Revision: 233882

URL: https://gcc.gnu.org/viewcvs?rev=233882&root=gcc&view=rev
Log:
	PR c++/68087

2016-03-01  Markus Trippelsdorf  <markus@trippelsdorf.de>
	    Paolo Carlini  <paolo.carlini@oracle.com>
/cp
	* constexpr.c (cxx_eval_array_reference): Use tree_fits_shwi_p before
	tree_to_shwi to avoid ICEs.

Modified:
    branches/gcc-5-branch/gcc/cp/ChangeLog
    branches/gcc-5-branch/gcc/cp/constexpr.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
    branches/gcc-5-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-array13.C
Comment 10 Christophe Lyon 2016-03-02 09:59:29 UTC
The backport on gcc-5-branch fails on ARM targets, because GCC complains with:
array subscript out of bound

The same test does pass on AArch64.
Comment 11 Christophe Lyon 2016-03-02 16:27:05 UTC
gcc-5-branch fixed by r233903.