blob: a5996c09755bf85323685810c9d5ff7406ad5d23 [file] [log] [blame]
/*
* Copyright (c) 2013 The Native Client Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "native_client/tests/toolchain/pic_constant_lib.h"
/*
* This is a regression test for:
* https://code.google.com/p/nativeclient/issues/detail?id=3549
* The compiler bug affected -fPIC compilations only.
*/
static const char *h(const char *s, size_t n) {
return n != 0 ? g(s, n) : s;
}
static const char *f(const char *s) {
return h(s, g(s, 0) - s);
}
const char *i(void) {
return f("string constant");
}
/*
* This is a regression test for:
* https://code.google.com/p/nativeclient/issues/detail?id=3598
* x86_64-nacl-gcc with optimization and -fPIC had a bug wherein it would
* attempt to generate an LEA instruction pattern using the full base
* register + index register + displacement addressing mode in compiling
* the trivial "sprint_nybble" function below, but then get an internal
* compiler error (and crash) because a PIC reference to a static variable
* is not usable as a displacement in an LEA instruction.
*/
static const char nybble[16][5]={
"0000", "0001", "0010", "0011",
"0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111"
};
/*
* The semantics for -fPIC require that a global function (with
* default visibility) be called via the PLT, so making this global
* truly ensures that main's call will not be inlined and so will be
* compiled as the general-case version that elicits the code
* pattern necessary to tickle the compiler bug. Conversely, with
* static and __attribute__((noinline)), while gcc-4.4 does what we
* want, gcc-4.8 doesn't inline per se, but replaces the standalone
* general-case function with a standalone (obeying noinline!)
* fully constant-propagated-and-folded variant that doesn't even do
* the table lookup at all!
*/
void sprint_nybble(int i, char s[4]) {
const char *c = nybble[i & 0x0f];
s[0] = c[0];
s[1] = c[1];
s[2] = c[2];
s[3] = c[3];
}