Bug 68810 - [8 regression] FAIL: g++.dg/cpp0x/constexpr-reinterpret1.C -- test for errors -- -m32
Summary: [8 regression] FAIL: g++.dg/cpp0x/constexpr-reinterpret1.C -- test for error...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.0
: P2 normal
Target Milestone: 8.0
Assignee: Jason Merrill
URL:
Keywords:
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2015-12-09 08:08 UTC by Tom de Vries
Modified: 2019-11-30 04:29 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-12-09 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2015-12-09 08:08:13 UTC
I'm seeing these failures at r231411 for x86_64 -m32:
...
FAIL: g++.dg/cpp0x/constexpr-reinterpret1.C  -std=c++11  (test for errors, line 21)
FAIL: g++.dg/cpp0x/constexpr-reinterpret1.C  -std=c++11 (test for excess errors)
FAIL: g++.dg/cpp0x/constexpr-reinterpret1.C  -std=c++14  (test for errors, line 21)
FAIL: g++.dg/cpp0x/constexpr-reinterpret1.C  -std=c++14 (test for excess errors)
...
Comment 1 Tom de Vries 2015-12-09 08:09:24 UTC
https://gcc.gnu.org/ml/gcc-regression/2015-12/msg00223.html confirms it as regression between r231329 and r231261
Comment 2 Tom de Vries 2015-12-09 08:13:01 UTC
In more detail, the c++11 failures look like this:
...
src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C: In static member function 'static constexpr B::Inner& B::getInner()':
src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C:20:14: error: reinterpret_cast from integer to pointer
compiler exited with status 1

FAIL: g++.dg/cpp0x/constexpr-reinterpret1.C  -std=c++11  (test for errors, line 21)
FAIL: g++.dg/cpp0x/constexpr-reinterpret1.C  -std=c++11 (test for excess errors)
...

The test for error is at line 21, the error is at line 20.
Comment 3 Tom de Vries 2015-12-09 08:23:57 UTC
The line of the error test seems to be recent:

d2c63826 (jason 2015-11-14 00:08:05 +0000 21)   } // { dg-error "reinterpret_cast" "" }                                           
e

Before, it was xfailed.

The title of the commit is "Merge C++ delayed folding branch"
Comment 4 Dominique d'Humieres 2015-12-09 18:13:43 UTC
Also seen on x86_64-apple-darwin14 in the range r231086 and r231311 (r231293?).
Comment 5 David Malcolm 2015-12-09 19:02:45 UTC
(In reply to vries from comment #3)
> The line of the error test seems to be recent:
> 
> d2c63826 (jason 2015-11-14 00:08:05 +0000 21)   } // { dg-error
> "reinterpret_cast" "" }                                           
> e
> 
> Before, it was xfailed.
> 
> The title of the commit is "Merge C++ delayed folding branch"

For reference, commit d2c638268e30dea7631ca2ee9b7489da2317526b was r230365.
Comment 6 David Malcolm 2015-12-09 19:22:22 UTC
The location of the error does indeed move from line 21 to line 20 upon adding -m32:

Here's recent trunk (r231296) on x86_64-pc-linux-gnu, running manually (without the -fno-diagnostics-show-caret from the test harness):

Without -m32:

$ ./xg++ \
    -B. \
    -c ../../src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C

../../src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C: In static member function ‘static constexpr B::Inner& B::getInner()’:
../../src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C:21:3: error: reinterpret_cast from integer to pointer
   } // { dg-error "reinterpret_cast" "" }
   ^

With -m32:

$ ./xg++ \
    -B. \
    -c ../../src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C \
    -m32

../../src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C: In static member function ‘static constexpr B::Inner& B::getInner()’:
../../src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C:20:14: error: reinterpret_cast from integer to pointer
     return *((Inner *)4);
             ~^~~~~~~~~~~
Comment 7 David Malcolm 2015-12-09 19:41:39 UTC
Error is emitted here in potential_constant_expression_1, in cp/constexpr.c:
4306		      error_at (EXPR_LOC_OR_LOC (t, input_location),
4307				"reinterpret_cast from integer to pointer");

With -m32 we have a CONVERT_EXPR with a location on line 20:

(gdb) call debug_tree (t)
 <convert_expr 0x7ffff19f4640
    type <pointer_type 0x7ffff19fa0a8
        type <record_type 0x7ffff19e57e0 Inner type_5 type_6 BLK
            size <integer_cst 0x7ffff19f2d50 constant 224>
            unit size <integer_cst 0x7ffff19f2d80 constant 28>
            align 32 symtab 0 alias set -1 canonical type 0x7ffff19e57e0 fields <field_decl 0x7ffff19f8390 m_Class> context <record_type 0x7ffff19e5690 B>
            full-name "class B::Inner"
            X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown
            pointer_to_this <pointer_type 0x7ffff19fa0a8> reference_to_this <reference_type 0x7ffff19e5f18> chain <type_decl 0x7ffff19e4ed8 Inner>>
        unsigned SI
        size <integer_cst 0x7ffff1891e58 constant 32>
        unit size <integer_cst 0x7ffff1891e70 constant 4>
        align 32 symtab 0 alias set -1 canonical type 0x7ffff19fa0a8>
    constant
    arg 0 <integer_cst 0x7ffff18b25b8 type <integer_type 0x7ffff18957e0 int> constant 4>
    ../../src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C:20:14 start: ../../src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C:20:13 finish: ../../src/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C:20:24>


Without -m32, we're dealing with a NOP_EXPR with unknown location, hence the use of input_location, which is at line 21:

(gdb) call debug_tree (t)
 <nop_expr 0x7ffff19f8900
    type <reference_type 0x7ffff19e9bd0
        type <record_type 0x7ffff19e9498 Inner type_5 type_6 BLK
            size <integer_cst 0x7ffff19f6ee8 constant 224>
            unit size <integer_cst 0x7ffff19f6f30 constant 28>
            align 32 symtab 0 alias set -1 canonical type 0x7ffff19e9498 fields <field_decl 0x7ffff19ea980 m_Class> context <record_type 0x7ffff19e9348 B>
            full-name "class B::Inner"
            X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown
            pointer_to_this <pointer_type 0x7ffff19e9e70> reference_to_this <reference_type 0x7ffff19e9bd0> chain <type_decl 0x7ffff19ea558 Inner>>
        unsigned DI
        size <integer_cst 0x7ffff1891e58 constant 64>
        unit size <integer_cst 0x7ffff1891e70 constant 8>
        align 64 symtab 0 alias set -1 canonical type 0x7ffff19e9bd0>
    constant
    arg 0 <integer_cst 0x7ffff19d6540 type <pointer_type 0x7ffff19e9e70> constant 4>>

so this may well be fallout from my C++ expression ranges patch (r231293); perhaps they both had unknown location previously?
Comment 8 Eric Botcazou 2015-12-11 07:17:34 UTC
Present on SPARC 32-bit as well.
Comment 9 David Edelsohn 2015-12-11 15:41:42 UTC
PowerPC -m32 (including AIX) also.
Comment 10 Thomas Preud'homme 2015-12-29 06:41:14 UTC
arm-none-eabi as well
Comment 11 Jakub Jelinek 2016-01-12 18:53:07 UTC
The reason for this is cp_convert_to_pointer doing:
228	  if (INTEGRAL_CODE_P (form))
229	    {
230	      if (TYPE_PRECISION (intype) == POINTER_SIZE)
231		return build1 (CONVERT_EXPR, type, expr);
232	      expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr,
233				 complain);
234	      /* Modes may be different but sizes should be the same.  There
235		 is supposed to be some integral type that is the same width
236		 as a pointer.  */
237	      gcc_assert (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
238			  == GET_MODE_SIZE (TYPE_MODE (type)));
239	
240	      return convert_to_pointer_nofold (type, expr);
241	    }

expr is INTEGER_CST 4, so for sizeof (void *) == sizeof (int) targets it unconditionally creates unfolded CONVERT_EXPR, which will hold the current input_location at that point (happens to be about right), while for sizeof (void *) != sizeof (int) targets it goes different path and (what happened to delayed folding here?) cp_convert actually folds it right away into long int 4L INTEGER_CST and convert_to_pointer_nofold (regardless of the *_nofold in the name) actually also folds it into INTEGER_CST 4 with pointer type.
Thus, unless we progress further with actual delayed folding, and/or unless we introduce also USE_EXPR trees holding uses of constants and decls, we are not going to resolve this.
So, for GCC6, I think best would be just to move the }:
--- constexpr-reinterpret1.C~	2015-11-14 19:35:49.000000000 +0100
+++ constexpr-reinterpret1.C	2016-01-12 19:52:00.114998687 +0100
@@ -17,8 +17,7 @@ public:
   constexpr static Inner & getInner()
   {
     /* I am surprised this is considered a constexpr */
-    return *((Inner *)4);
-  } // { dg-error "reinterpret_cast" "" }
+    return *((Inner *)4); } // { dg-error "reinterpret_cast" "" }
 };
 
 B B::instance;
so that it really doesn't matter where it is reported.  And work more on C++ delayed folding for GCC 7.
Comment 12 Jakub Jelinek 2016-01-21 20:30:08 UTC
Author: jakub
Date: Thu Jan 21 20:29:33 2016
New Revision: 232705

URL: https://gcc.gnu.org/viewcvs?rev=232705&root=gcc&view=rev
Log:
	PR c++/68810
	* g++.dg/cpp0x/constexpr-reinterpret1.C: Fix line number that is                                                                           
	expected to generate an error.                                                                                                             

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C
Comment 13 Jakub Jelinek 2016-01-21 20:44:37 UTC
Testcase adjusted, for GCC 7 we should improve the locus even for the targets where the pointer size is different from int's type.
Comment 14 Jason Merrill 2016-07-11 19:17:34 UTC
The testcase fix is good enough for GCC 6.
Comment 15 Jakub Jelinek 2017-01-10 13:29:54 UTC
I'd say this is very much related to the missing USE_DECL/USE_CONST trees; the testcase works right now, and it is too late to introduce these in GCC 7, so I'll defer for GCC 8.
Comment 16 Jakub Jelinek 2017-12-01 17:56:56 UTC
David, does your patchset solve this?
Comment 17 David Malcolm 2017-12-04 15:26:27 UTC
(In reply to Jakub Jelinek from comment #16)
> David, does your patchset solve this?

The v2 version of the kit
  https://gcc.gnu.org/ml/gcc-patches/2017-11/msg00880.html
doesn't affect it.

The work-in-progress v3 version of the kit
  https://gcc.gnu.org/ml/gcc-patches/2017-11/msg01588.html
actually breaks the warning, stopping it from appearing altogether (this turns out to be one of the regressions mentioned in that post).  I'm investigating why.
Comment 18 David Malcolm 2017-12-04 15:29:20 UTC
...but presumably a question here is "what is the ideal output of the compiler for that code?", and the answer might be:

constexpr-reinterpret1.C:19:??: error: reinterpret_cast from integer to pointer
   { return *((Inner *)4); }
              ^~~~~~~~~~

and it ought to be possible to implement that with the more ambitious v3 patch kit.
Comment 19 Jason Merrill 2018-01-29 20:56:32 UTC
Author: jason
Date: Mon Jan 29 20:56:00 2018
New Revision: 257161

URL: https://gcc.gnu.org/viewcvs?rev=257161&root=gcc&view=rev
Log:
	PR c++/68810 - wrong location for reinterpret_cast error.

	* cvt.c (cp_convert_to_pointer): Always build a CONVERT_EXPR when
	!dofold.

Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cvt.c
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-reinterpret1.C
Comment 20 Jason Merrill 2018-01-29 20:57:26 UTC
Fixed, though we're still folding too many things.