[PATCH] Reject > word sign extensions in initializers (PR middle-end/80163)

Jakub Jelinek jakub@redhat.com
Fri Mar 24 19:31:00 GMT 2017


Hi!

I'm not aware of any target that would support sign extension of
something that can't be folded in the compiler into some type
larger than word/pointer.  Zero extension is doable and assemble_variable
is able to deal with it by emitting low/high subregs of it (where the
low one will contain some expression that needs to be computed by assembler
or even have relocation and upper part will be all zeros), but for
sign extension we'd need assembler support that would for some
asm expression shift it arithmetically right.

So, this patch just rejects it in initializers (in C++ handles through
dynamic initialization) in that case.  clang also rejects it, ICC silently
miscompiles (performs zero extension).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-03-24  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/80163
	* varasm.c (initializer_constant_valid_p_1): Disallow sign-extending
	conversions to integer types wider than word and pointer.

	* gcc.dg/pr80163.c: New test.

--- gcc/varasm.c.jj	2017-01-01 12:45:37.000000000 +0100
+++ gcc/varasm.c	2017-03-24 13:03:37.489529361 +0100
@@ -4472,8 +4472,15 @@ initializer_constant_valid_p_1 (tree val
 	  return initializer_constant_valid_p_1 (src, endtype, cache);
 
 	/* Allow conversions between other integer types only if
-	   explicit value.  */
-	if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type))
+	   explicit value.  Don't allow sign-extension to a type larger
+	   than word and pointer, there aren't relocations that would
+	   allow to sign extend it to a wider type.  */
+	if (INTEGRAL_TYPE_P (dest_type)
+	    && INTEGRAL_TYPE_P (src_type)
+	    && (TYPE_UNSIGNED (src_type)
+		|| TYPE_PRECISION (dest_type) <= TYPE_PRECISION (src_type)
+		|| TYPE_PRECISION (dest_type) <= BITS_PER_WORD
+		|| TYPE_PRECISION (dest_type) <= POINTER_SIZE))
 	  {
 	    tree inner = initializer_constant_valid_p_1 (src, endtype, cache);
 	    if (inner == null_pointer_node)
--- gcc/testsuite/gcc.dg/pr80163.c.jj	2017-03-24 13:02:37.827295587 +0100
+++ gcc/testsuite/gcc.dg/pr80163.c	2017-03-24 13:05:12.465309614 +0100
@@ -0,0 +1,22 @@
+/* PR middle-end/80163 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O0" } */
+
+void bar (void);
+
+__int128_t *
+foo (void)
+{
+a:
+  bar ();
+b:;
+  static __int128_t d = (long) &&a - (long) &&b;	/* { dg-error "initializer element is not computable at load time" } */
+  return &d;
+}
+
+__int128_t *
+baz (void)
+{
+  static __int128_t d = (long) (3 * 4);
+  return &d;
+}

	Jakub



More information about the Gcc-patches mailing list