insert_value_copy_on_edge declares 'unsignedp' uninitialized and sets it
only as a side effect of an argument to gcc_assert.  When src_mode and
dest_mode differ it is then passed to convert_modes, which uses it to
choose between zero and sign extension.

gcc_assert does not always evaluate its argument.  With GCC_VERSION
< 4005 and without assert checking, gcc/system.h defines

  #define gcc_assert(EXPR) ((void)(0 && (EXPR)))

so promote_ssa_mode is never called and unsignedp is passed to
convert_modes indeterminate, selecting zero or sign extension at random.
GCC_VERSION is __GNUC__ * 1000 + __GNUC_MINOR__, so any host compiler
reporting less than 4.5 takes this branch.

Relying on a side effect in gcc_assert is against the coding
conventions regardless of which expansion is in use.  Call
promote_ssa_mode outside the assert, as the same file already does in
get_temp_reg, and keep the assert for the invariant alone.  unsignedp is
initialized for the !REG_P path, where promote_ssa_mode is not called.

Signed-off-by: Sam Price <[email protected]>
Assisted-by: Claude (Anthropic)
---

Found while getting gcc.c-torture running against a MicroBlaze port to
LLVM, comparing the two compilers over the suite.

 gcc/tree-outof-ssa.cc | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/gcc/tree-outof-ssa.cc b/gcc/tree-outof-ssa.cc
index f4bc4878bd6ca..65fb2e16ea4ed 100644
--- a/gcc/tree-outof-ssa.cc
+++ b/gcc/tree-outof-ssa.cc
@@ -308,7 +308,7 @@ insert_value_copy_on_edge (edge e, int dest, tree src, 
location_t locus)
 {
   rtx dest_rtx, seq, x;
   machine_mode dest_mode, src_mode;
-  int unsignedp;
+  int unsignedp = 0;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -334,8 +334,11 @@ insert_value_copy_on_edge (edge e, int dest, tree src, 
location_t locus)
   src_mode = TYPE_MODE (TREE_TYPE (src));
   dest_mode = GET_MODE (dest_rtx);
   gcc_assert (src_mode == TYPE_MODE (TREE_TYPE (name)));
-  gcc_assert (!REG_P (dest_rtx)
-             || dest_mode == promote_ssa_mode (name, &unsignedp));
+  if (REG_P (dest_rtx))
+    {
+      machine_mode pmode = promote_ssa_mode (name, &unsignedp);
+      gcc_assert (dest_mode == pmode);
+    }
 
   if (src_mode != dest_mode)
     {

Reply via email to