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.
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
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.
*** Bug 83166 has been marked as a duplicate of this bug. ***
(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.
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;
(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); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BZ mangled the underline a bit in comment #6; the caret is on the '-' character, like this simplified version: thunk->callback = LHS - RHS; ~~~~^~~~~
This is a checking ICE, not a user facing diagnostics. Not need to spend time on anything but fixing the ICE.
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.
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.
(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!
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
Fixed.