Bug 66211 - [5 Regression] Rvalue conversion in ternary operator causes internal compiler error
Summary: [5 Regression] Rvalue conversion in ternary operator causes internal compiler...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.1.0
: P3 normal
Target Milestone: 5.2
Assignee: Richard Biener
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-05-20 03:58 UTC by Vlad Gheorghiu
Modified: 2015-06-03 07:41 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 5.2.0, 6.0
Known to fail: 5.1.0
Last reconfirmed: 2015-05-20 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vlad Gheorghiu 2015-05-20 03:58:35 UTC
The code below

void f(int&){}

int main()
{
    int x = 0;
    double y = 1;
    f(1 > 0 ? x : y);
}

should not compile, due to rvalue conversion in the ternary operator, then trying to bind the rvalue to a non-constant reference. However, gcc51 and gcc6 HEAD crash with an internal compiler error

     internal compiler error: in convert_like_real, at cp/call.c:6471

gcc49 works (emits an error)
Comment 1 Jakub Jelinek 2015-05-20 07:07:24 UTC
Started with r217279.
Comment 2 Richard Biener 2015-05-20 07:39:21 UTC
I will have a look.
Comment 3 Richard Biener 2015-05-20 08:19:47 UTC
So we fold (and did fold before) 1 > 0 ? x : y to (float) x (thus an rvalue).
Then later we call ocp_convert on that requesting a conversion to int which does

810           converted = fold_if_not_in_template (convert_to_integer (type, e));

where convert_to_integer ends up just doing

910             return build1 (FIX_TRUNC_EXPR, type, expr);

and fold then applying the simplification

   /* If we are converting an integer to a floating-point that can
      represent it exactly and back to an integer, we can skip the
      floating-point conversion.  */
   (if (inside_int && inter_float && final_int &&
        (unsigned) significand_size (TYPE_MODE (inter_type))
        >= inside_prec - !inside_unsignedp)
    (convert @0))))))

and

(for cvt (convert view_convert float fix_trunc)
 (simplify
  (cvt @0)
  (if ((GIMPLE && useless_type_conversion_p (type, TREE_TYPE (@0)))
       || (GENERIC && type == TREE_TYPE (@0)))
   @0)))

where wrapping the result as (non_lvalue @0) fixes the regression.  The bug
is of course the C++ frontend folding stuff too early (and too aggressive)
here.

But for GCC 5 the above might be a good-enough workaround (eventually
we can conditionalize building non_lvalue exprs to non-C-frontends).
Comment 4 Richard Biener 2015-05-20 13:04:06 UTC
Unfortunately this causes

FAIL: gcc.dg/tree-ssa/foldcast-1.c scan-tree-dump-times original "return x;" 2
FAIL: gcc.dg/tree-ssa/pr31261.c scan-tree-dump-times original "return b & 7;" 1

FAIL: gfortran.dg/assumed_type_2.f90   -O0   scan-tree-dump-times original "sub_
scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/assumed_type_2.f90   -O1   scan-tree-dump-times original "sub_
scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/assumed_type_2.f90   -O2   scan-tree-dump-times original "sub_
scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/assumed_type_2.f90   -O3 -fomit-frame-pointer   scan-tree-dump
-times original "sub_scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat"
 1
FAIL: gfortran.dg/assumed_type_2.f90   -O3 -fomit-frame-pointer -funroll-all-loo
ps -finline-functions   scan-tree-dump-times original "sub_scalar .\\\\(struct t
1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/assumed_type_2.f90   -O3 -fomit-frame-pointer -funroll-loops  
 scan-tree-dump-times original "sub_scalar .\\\\(struct t1 .\\\\) array_class_t1
_ptr._data.dat" 1
FAIL: gfortran.dg/assumed_type_2.f90   -O3 -g   scan-tree-dump-times original "s
ub_scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/assumed_type_2.f90   -Os   scan-tree-dump-times original "sub_
scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/c_f_pointer_tests_3.f90   -O   scan-tree-dump-times original "
 fptr_array.data = cptr;" 1
FAIL: gfortran.dg/c_loc_test_22.f90   -O   scan-tree-dump-times original "D.[0-9
]+ = parm.[0-9]+.data;[^;]+ptr[1-4] = D.[0-9]+;" 4
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O0   scan-tree-dump-times original "fgsl
_file.[0-9]+.gsl_file = c_ptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O0   scan-tree-dump-times original "fgsl
_file.[0-9]+.gsl_func = c_funptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O1   scan-tree-dump-times original "fgsl
_file.[0-9]+.gsl_file = c_ptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O1   scan-tree-dump-times original "fgsl
_file.[0-9]+.gsl_func = c_funptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O2   scan-tree-dump-times original "fgsl
_file.[0-9]+.gsl_file = c_ptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O2   scan-tree-dump-times original "fgsl
_file.[0-9]+.gsl_func = c_funptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O3 -fomit-frame-pointer   scan-tree-dump
-times original "fgsl_file.[0-9]+.gsl_file = c_ptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O3 -fomit-frame-pointer   scan-tree-dump
-times original "fgsl_file.[0-9]+.gsl_func = c_funptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O3 -fomit-frame-pointer -funroll-all-loo
ps -finline-functions   scan-tree-dump-times original "fgsl_file.[0-9]+.gsl_file
 = c_ptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O3 -fomit-frame-pointer -funroll-all-loo
ps -finline-functions   scan-tree-dump-times original "fgsl_file.[0-9]+.gsl_func
 = c_funptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O3 -fomit-frame-pointer -funroll-loops  
 scan-tree-dump-times original "fgsl_file.[0-9]+.gsl_file = c_ptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O3 -fomit-frame-pointer -funroll-loops  
 scan-tree-dump-times original "fgsl_file.[0-9]+.gsl_func = c_funptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O3 -g   scan-tree-dump-times original "f
gsl_file.[0-9]+.gsl_file = c_ptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -O3 -g   scan-tree-dump-times original "f
gsl_file.[0-9]+.gsl_func = c_funptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -Os   scan-tree-dump-times original "fgsl
_file.[0-9]+.gsl_file = c_ptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_14.f90   -Os   scan-tree-dump-times original "fgsl
_file.[0-9]+.gsl_func = c_funptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_15.f90   -O   scan-tree-dump-times original "fgsl_
file.[0-9]+.gsl_file = c_ptr.[0-9]+;" 1
FAIL: gfortran.dg/c_ptr_tests_15.f90   -O   scan-tree-dump-times original "fgsl_
file.[0-9]+.gsl_func = c_funptr.[0-9]+;" 1
FAIL: gfortran.dg/coarray_31.f90   -O   scan-tree-dump original "a.y.d._data.dat
a = D.[0-9]+.y.d._data.data;"
FAIL: gfortran.dg/coarray_31.f90   -O   scan-tree-dump original "a.y.x.data = D.
[0-9]+.y.x.data;"
FAIL: gfortran.dg/coarray_31.f90   -O   scan-tree-dump original "a.y.z._data.dat
a = D.[0-9]+.y.z._data.data;"
FAIL: gfortran.dg/no_arg_check_2.f90   -O0   scan-tree-dump-times original "sub_
scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/no_arg_check_2.f90   -O1   scan-tree-dump-times original "sub_
scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/no_arg_check_2.f90   -O2   scan-tree-dump-times original "sub_
scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/no_arg_check_2.f90   -O3 -fomit-frame-pointer   scan-tree-dump
-times original "sub_scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat"
 1
FAIL: gfortran.dg/no_arg_check_2.f90   -O3 -fomit-frame-pointer -funroll-all-loo
ps -finline-functions   scan-tree-dump-times original "sub_scalar .\\\\(struct t
1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/no_arg_check_2.f90   -O3 -fomit-frame-pointer -funroll-loops  
 scan-tree-dump-times original "sub_scalar .\\\\(struct t1 .\\\\) array_class_t1
_ptr._data.dat" 1
FAIL: gfortran.dg/no_arg_check_2.f90   -O3 -g   scan-tree-dump-times original "s
ub_scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat" 1
FAIL: gfortran.dg/no_arg_check_2.f90   -Os   scan-tree-dump-times original "sub_
scalar .\\\\(struct t1 .\\\\) array_class_t1_ptr._data.dat" 1

FAIL: gnat.dg/ice_type.adb (test for excess errors) (ICE in build_binary_op, at ada/gcc-interface/utils2.c:906)
FAIL: gnat.dg/specs/addr1.ads  (test for warnings, line 30)


not yet further analyzed.

IMHO the C++ frontend shouldn't rely on fold preserving rvalue-ness but it
should perform these checks before folding like the C frontend does.


I'll look at the above failures later this week to see if there is anything
obvious that can be improved.
Comment 5 Jakub Jelinek 2015-05-20 13:12:10 UTC
Perhaps just guard this particular match.pd pattern with GIMPLE guard for now (until the delayed C++ folding is committed)?
Comment 6 rguenther@suse.de 2015-05-21 07:48:32 UTC
On Wed, 20 May 2015, jakub at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66211
> 
> --- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
> Perhaps just guard this particular match.pd pattern with GIMPLE guard for now
> (until the delayed C++ folding is committed)?

Will try.
Comment 7 Richard Biener 2015-05-21 13:24:12 UTC
Fixed on trunk sofar.
Comment 8 Richard Biener 2015-05-21 13:24:13 UTC
Author: rguenth
Date: Thu May 21 13:23:41 2015
New Revision: 223483

URL: https://gcc.gnu.org/viewcvs?rev=223483&root=gcc&view=rev
Log:
2015-05-21  Richard Biener  <rguenther@suse.de>

	PR c++/66211
	* match.pd: Guard pattern optimzing (int)(float)int
	conversions to apply only on GIMPLE.

	* g++.dg/conversion/pr66211.C: New testcase.
	* gcc.dg/tree-ssa/forwprop-18.c: Adjust.

Added:
    trunk/gcc/testsuite/g++.dg/conversion/pr66211.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/match.pd
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/tree-ssa/forwprop-18.c
Comment 9 Richard Biener 2015-06-03 07:39:38 UTC
Author: rguenth
Date: Wed Jun  3 07:39:06 2015
New Revision: 224059

URL: https://gcc.gnu.org/viewcvs?rev=224059&root=gcc&view=rev
Log:
2015-06-03  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2015-06-02  Richard Biener  <rguenther@suse.de>

	PR debug/65549
	* dwarf2out.c (lookup_context_die): New function.
	(resolve_addr): Avoid forcing a full DIE for the
	target of a DW_TAG_GNU_call_site during late compilation.
	Instead create a stub DIE without a type if we have a
	context DIE present.

	* g++.dg/lto/pr65549_0.C: New testcase.

	2015-06-01  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/66280
	* tree-vect-slp.c (vect_detect_hybrid_slp_stmts): Fix pattern
	def-use walking.

	* g++.dg/torture/pr66280.C: New testcase.
	* g++.dg/torture/pr66280-2.C: Likewise.

	2015-05-27  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/66272
	Revert parts of
	2014-08-15  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/62031
	* tree-data-ref.c (dr_analyze_indices): Do not set
	DR_UNCONSTRAINED_BASE.
	(dr_may_alias_p): All indirect accesses have to go the
	formerly DR_UNCONSTRAINED_BASE path.
	* tree-data-ref.h (struct indices): Remove
	unconstrained_base member.
	(DR_UNCONSTRAINED_BASE): Remove.

	* gcc.dg/torture/pr66272.c: New testcase.

	2015-05-21  Richard Biener  <rguenther@suse.de>

	PR c++/66211
	* match.pd: Guard pattern optimzing (int)(float)int
	conversions to apply only on GIMPLE.

	* g++.dg/conversion/pr66211.C: New testcase.
	* gcc.dg/tree-ssa/forwprop-18.c: Adjust.

	2015-05-13  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/66123
	* tree-ssa-dom.c (propagate_rhs_into_lhs): Check if we found
	a taken edge.

	* gcc.dg/torture/pr66123.c: New testcase.

Added:
    branches/gcc-5-branch/gcc/testsuite/g++.dg/conversion/pr66211.C
    branches/gcc-5-branch/gcc/testsuite/g++.dg/lto/pr65549_0.C
    branches/gcc-5-branch/gcc/testsuite/g++.dg/torture/pr66280-2.C
    branches/gcc-5-branch/gcc/testsuite/g++.dg/torture/pr66280.C
    branches/gcc-5-branch/gcc/testsuite/gcc.dg/torture/pr66123.c
    branches/gcc-5-branch/gcc/testsuite/gcc.dg/torture/pr66272.c
Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/dwarf2out.c
    branches/gcc-5-branch/gcc/match.pd
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
    branches/gcc-5-branch/gcc/testsuite/gcc.dg/tree-ssa/forwprop-18.c
    branches/gcc-5-branch/gcc/tree-data-ref.c
    branches/gcc-5-branch/gcc/tree-data-ref.h
    branches/gcc-5-branch/gcc/tree-ssa-dom.c
    branches/gcc-5-branch/gcc/tree-vect-slp.c
Comment 10 Richard Biener 2015-06-03 07:41:18 UTC
Fixed.