Bug 83164 - [8 regression] internal compiler error: verify_gimple failed
Summary: [8 regression] internal compiler error: verify_gimple failed
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: 8.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-checking
: 83166 (view as bug list)
Depends on:
Blocks:
 
Reported: 2017-11-26 00:08 UTC by Gerald Pfeifer
Modified: 2017-12-07 17:11 UTC (History)
4 users (show)

See Also:
Host: i586-unknown-freebsd10.4
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-11-26 00:00:00


Attachments
Preprocessed source file (55.18 KB, text/plain)
2017-11-26 00:08 UTC, Gerald Pfeifer
Details
gcc8-pr83164.patch (584 bytes, patch)
2017-12-07 12:06 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Gerald Pfeifer 2017-11-26 00:08:41 UTC
Created attachment 42718 [details]
Preprocessed source file

This one's easy to reproduce, no specific compiler options are required:

% $GCC -c -o ddeml.o ddeml.i
ddeml.c: In function ‘DDEML_AddThunk’:
ddeml.c:181:28: error: type mismatch in pointer diff expression
 static struct ddeml_thunk*      DDEML_AddThunk(DWORD instId, DWORD pfn16)
                            ^~~~~~~~~~~~~~
int

struct HDDEDATA__ * (*<T1c96>) (DWORD, UINT, UINT, struct HCONV__ *, struct HSZ__ *, struct HSZ__ *, struct HDDEDATA__ *, ULONG_PTR, ULONG_PTR)

DWORD *

_6 = WDML_InvokeCallback16 - _5;
ddeml.c:181:28: internal compiler error: verify_gimple failed



Also the diagnostics look quite odd, don't they?


I believe this was introduced by the following?

2017-10-28  Marc Glisse  <marc.glisse@inria.fr>

gcc/c/
        * c-fold.c (c_fully_fold_internal): Handle POINTER_DIFF_EXPR.
        * c-typeck.c (pointer_diff): Use POINTER_DIFF_EXPR.

gcc/c-family/
        * c-pretty-print.c (pp_c_additive_expression,
        c_pretty_printer::expression): Handle POINTER_DIFF_EXPR.

gcc/cp/
        * constexpr.c (cxx_eval_constant_expression,
        potential_constant_expression_1): Handle POINTER_DIFF_EXPR.
        * cp-gimplify.c (cp_fold): Likewise.
        * error.c (dump_expr): Likewise.
        * typeck.c (pointer_diff): Use POINTER_DIFF_EXPR.
Comment 1 Marc Glisse 2017-11-26 00:20:47 UTC
void b() { long a = (char *)b - (char *)1; }


ddeml.i: In function 'b':
ddeml.i:1:6: error: type mismatch in pointer diff expression
 void b() { long a = (char *)b - (char *)1; }
      ^
long int

void (*<T2f9>) ()

char *

a = b - 1B;
ddeml.i:1:6: internal compiler error: verify_gimple failed
0xdafba4 verify_gimple_in_seq(gimple*)
	/home/glisse/repos/gcc/trunk/gcc/tree-cfg.c:5094
0xb534ae gimplify_body(tree_node*, bool)
	/home/glisse/repos/gcc/trunk/gcc/gimplify.c:12606
0xb5369d gimplify_function_tree(tree_node*)
	/home/glisse/repos/gcc/trunk/gcc/gimplify.c:12696
0x9ddb4f cgraph_node::analyze()
	/home/glisse/repos/gcc/trunk/gcc/cgraphunit.c:670
0x9e0765 analyze_functions
	/home/glisse/repos/gcc/trunk/gcc/cgraphunit.c:1131
0x9e1432 symbol_table::finalize_compilation_unit()
	/home/glisse/repos/gcc/trunk/gcc/cgraphunit.c:2690
Comment 2 Marc Glisse 2017-11-26 00:49:55 UTC
Does it work if you remove the verification

            || !types_compatible_p (rhs1_type, rhs2_type)

from tree-cfg.c?

useless_type_conversion_p says that converting a function pointer to char* is useless (but the reverse isn't), so we can't guarantee types_compatible_p.
Comment 3 Marc Glisse 2017-11-26 00:52:24 UTC
*** Bug 83166 has been marked as a duplicate of this bug. ***
Comment 4 Gerald Pfeifer 2017-11-26 10:11:06 UTC
(In reply to Marc Glisse from comment #2)
> Does it work if you remove the verification
> 
>             || !types_compatible_p (rhs1_type, rhs2_type)
> 
> from tree-cfg.c?

Yes, I just tried this.
Comment 5 Richard Biener 2017-11-27 08:54:14 UTC
comparison verification has

  /* For comparisons we do not have the operations type as the
     effective type the comparison is carried out in.  Instead
     we require that either the first operand is trivially
     convertible into the second, or the other way around.
     Because we special-case pointers to void we allow
     comparisons of pointers with the same mode as well.  */
  if (!useless_type_conversion_p (op0_type, op1_type)
      && !useless_type_conversion_p (op1_type, op0_type)
      && (!POINTER_TYPE_P (op0_type)
          || !POINTER_TYPE_P (op1_type)
          || TYPE_MODE (op0_type) != TYPE_MODE (op1_type)))
    {

which works around a similar issue there (the comment is outdated).

IIRC the following is to not wreck targets with function descriptors
where the conversion generates code(?)  I'd be very happy to get rid
of this special case and/or if this is really the case make it
more explicit somehow.

bool
useless_type_conversion_p (tree outer_type, tree inner_type)
{
  /* Do the following before stripping toplevel qualifiers.  */
  if (POINTER_TYPE_P (inner_type)
      && POINTER_TYPE_P (outer_type))
    {
...
      /* Do not lose casts to function pointer types.  */
      if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
           || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
          && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE
               || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE))
        return false;
Comment 6 David Malcolm 2017-11-27 15:36:08 UTC
(In reply to Gerald Pfeifer from comment #0)
[...]
> Also the diagnostics look quite odd, don't they?
[...]

If I strip out the line directives from the .i file, then I get:

ddeml.i:8322:28: error: type mismatch in pointer diff expression
 static struct ddeml_thunk* DDEML_AddThunk(DWORD instId, DWORD pfn16)
                            ^~~~~~~~~~~~~~

from this line in tree-cfg.c:

3996		    error ("type mismatch in pointer diff expression");

which is less odd (though not great).

If I use stmt->location for the diagnostic (rather than the implicit use of input_location), then I get the much more useful:

(gdb) call inform (stmt->location, "")
ddeml.i: In function ‘DDEML_AddThunk’:
ddeml.i:8342:61: note: 
             thunk->callback = (char *)WDML_InvokeCallback16 - (char *)(&thunk->callback + 1);
                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 7 David Malcolm 2017-11-27 15:38:04 UTC
BZ mangled the underline a bit in comment #6; the caret is on the '-' character, like this simplified version:

thunk->callback = LHS - RHS;
                  ~~~~^~~~~
Comment 8 Jakub Jelinek 2017-11-27 16:05:40 UTC
This is a checking ICE, not a user facing diagnostics.  Not need to spend time on anything but fixing the ICE.
Comment 9 Jakub Jelinek 2017-12-07 12:06:48 UTC
Created attachment 42810 [details]
gcc8-pr83164.patch

So like this?  It makes no sense to call types_compatible_p or 2x useless_type_conversion_p if TYPE_MODE is different, because we know the result - it will not be compatible.  And anything else needs to be allowed due to the propagation of pointers.
Comment 10 rguenther@suse.de 2017-12-07 12:12:10 UTC
On Thu, 7 Dec 2017, jakub at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83164
> 
> --- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
> Created attachment 42810 [details]
>   --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42810&action=edit
> gcc8-pr83164.patch
> 
> So like this?  It makes no sense to call types_compatible_p or 2x
> useless_type_conversion_p if TYPE_MODE is different, because we know the result
> - it will not be compatible.  And anything else needs to be allowed due to the
> propagation of pointers.
>

Yes, this is ok.
Comment 11 Marc Glisse 2017-12-07 12:22:45 UTC
(In reply to Jakub Jelinek from comment #9)
> Created attachment 42810 [details]
> gcc8-pr83164.patch

Sorry, I shouldn't have taken this long.

> So like this?  It makes no sense to call types_compatible_p or 2x
> useless_type_conversion_p if TYPE_MODE is different, because we know the
> result - it will not be compatible.  And anything else needs to be allowed
> due to the propagation of pointers.

This looks great!
Comment 12 Jakub Jelinek 2017-12-07 17:06:39 UTC
Author: jakub
Date: Thu Dec  7 17:06:08 2017
New Revision: 255470

URL: https://gcc.gnu.org/viewcvs?rev=255470&root=gcc&view=rev
Log:
	PR middle-end/83164
	* tree-cfg.c (verify_gimple_assign_binary): Don't require
	types_compatible_p, just that TYPE_MODE is the same.

	* gcc.c-torture/compile/pr83164.c: New test.

Added:
    trunk/gcc/testsuite/gcc.c-torture/compile/pr83164.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-cfg.c
Comment 13 Jakub Jelinek 2017-12-07 17:11:24 UTC
Fixed.