> # BLOCK 6 > # PRED: 4 (false,exec) > <L1>:; > iftmp.78_63 = D.1309_32; > iftmp.78_64 = D.1309_32; > D.1316_65 = (c460008__unsigned_edge_8) D.1309_32; > if (D.1316_65 == 255) goto <L3>; else goto <L4>; > # SUCC: 7 (true,exec) 8 (false,exec) > [...] > The problem (of course) is D.1316_65 can and does actually hold > values outside the range [ ,254] at runtime. For example, it could > hold the value 255 if D.1309_32 had the value 255, which would occur > if for_the_value_31 held the value 255000000000. > > Someone with a better knowledge of Ada is going to need to step > in here, but based on the type information provided by the Ada > front-end, VRP is doing the right thing here.
Yes, I think we have a problem in Gigi, namely convert_with_check: Breakpoint 5, convert_with_check (gnat_type=2517, gnu_expr=0x5572c45c, overflowp=1 '\001', rangep=1 '\001', truncatep=0 '\0') at /home/eric/svn/gcc/gcc/ada/trans.c:5322 5322 tree gnu_type = get_unpadded_type (gnat_type); 5323 tree gnu_in_type = TREE_TYPE (gnu_expr); 5324 tree gnu_in_basetype = get_base_type (gnu_in_type); 5325 tree gnu_base_type = get_base_type (gnu_type); 5326 tree gnu_ada_base_type = get_ada_base_type (gnu_type); 5327 tree gnu_result = gnu_expr; (gdb) p debug_tree(gnu_type) <integer_type 0x55723958 c460008__fixed_to_shortGP1192__target type <integer_type 0x55723678 c460008__unsigned_edge_8 type <integer_type 0x5572361c c460008__unsigned_edge_8___UMT public unsigned type_1 QI (gdb) p debug_tree(gnu_base_type) <integer_type 0x5572361c c460008__unsigned_edge_8___UMT public unsigned type_1QI (gdb) p debug_tree(gnu_ada_base_type) <integer_type 0x55723678 c460008__unsigned_edge_8 type <integer_type 0x5572361c c460008__unsigned_edge_8___UMT public unsigned type_1 QI 5482 gnu_result = convert (gnu_ada_base_type, gnu_result); 5488 if (rangep 5491 gnu_result = emit_range_check (gnu_result, gnat_type); 5493 return convert (gnu_type, gnu_result); We convert to gnu_ada_base_type before emitting the check using gnu_base_type. If you slightly thwart the constant folder, the t.gimple output looks like: D.756 = for_the_value /[rd] 1000000000; D.757 = (UNSIGNED_64) D.756; if (D.757 > 255) { __gnat_rcheck_10 ("c460008.adb", 35); iftmp.5 = for_the_value /[rd] 1000000000; } else { iftmp.5 = for_the_value /[rd] 1000000000; } iftmp.6 = iftmp.5; if (0) { goto <D760>; } else { } D.763 = (c460008__unsigned_edge_8) iftmp.6; D.764 = (c460008__unsigned_edge_8___UMT) D.763; if (D.764 > 254) { goto <D760>; } else { goto <D761>; } <D760>:; __gnat_rcheck_12 ("c460008.adb", 35); The problematic line is D.763 = (c460008__unsigned_edge_8) iftmp.6; Excerpt from utils2.c: /* Likewise, but only return types known to the Ada source. */ tree get_ada_base_type (tree type) { while (TREE_TYPE (type) && (TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == REAL_TYPE) && !TYPE_EXTRA_SUBTYPE_P (type)) type = TREE_TYPE (type); return type; } And ada-tree.h: /* Nonzero in an arithmetic subtype if this is a subtype not known to the front-end. */ #define TYPE_EXTRA_SUBTYPE_P(NODE) TYPE_LANG_FLAG_2 (NODE) c460008__unsigned_edge_8 has the TYPE_EXTRA_SUBTYPE_P flag set. -- Eric Botcazou