Clang Linux driver - header directories for wrong architecture are selected for -m32

Hello,

I have a problem with current Clang master: it selects x64 headers for 32-bit architecture and it leads to compiler errors.
I have Ubuntu 14.04 with GCC-4.8.2 and 4.6.4 installed + multilib. Clang 3.5 (master) doesn't add "/32" suffixes if "-m32" option is specified.
Sample code:

#include <iostream>
#include <limits>

int main() {
   std::cout << "Hello world!\n";
}

-### command:
-### -c -m32 test.cpp

Output (clang-3.4, compilation is OK):
clang version 3.4
Target: i386-unknown-linux-gnu
Thread model: posix
"-cc1" "-triple" "i386-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "01.cpp" "-mrelocation-model" "static" "-mdisable-fp-elim" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-fuse-init-array" "-target-cpu" "pentium4" "-coverage-file" "/media/partition/android-4.2.1/01.o" "-resource-dir" "/media/build/smrc-llvm/llvm-new/qtcreator-build/bin/../lib/clang/3.4" "-internal-isystem" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8" "-internal-isystem" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu/32" "-internal-isystem" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" "-internal-isystem" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/32" "-internal-isystem" "/usr/local/include" "-internal-isystem" "/media/build/smrc-llvm/llvm-new/qtcreator-build/bin/../lib/clang/3.4/include" "-internal-externc-isystem" "/usr/include/i386-linux-gnu" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdeprecated-macro" "-fdebug-compilation-dir" "/media/partition/android-4.2.1" "-ferror-limit" "19" "-fmessage-length" "229" "-mstackrealign" "-fobjc-runtime=gcc" "-fcxx-exceptions" "-fexceptions" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-vectorize-slp" "-o" "01.o" "-x" "c++" "01.cpp"

Output(clang-3.5):
clang version 3.5.0
Target: i386-unknown-linux-gnu
Thread model: posix
"-cc1" "-triple" "i386-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "01.cpp" "-mrelocation-model" "static" "-mdisable-fp-elim" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-fuse-init-array" "-target-cpu" "pentium4" "-coverage-file" "/media/partition/android-4.2.1/01.o" "-resource-dir" "/media/build/smrc-llvm/master/qtcreator-build/bin/../lib/clang/3.5.0" "-internal-isystem" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8" "-internal-isystem" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu" "-internal-isystem" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward" "-internal-isystem" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8" "-internal-isystem" "/usr/local/include" "-internal-isystem" "/media/build/smrc-llvm/master/qtcreator-build/bin/../lib/clang/3.5.0/include" "-internal-externc-isystem" "/usr/include/i386-linux-gnu" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdeprecated-macro" "-fdebug-compilation-dir" "/media/partition/android-4.2.1" "-ferror-limit" "19" "-fmessage-length" "229" "-mstackrealign" "-fobjc-runtime=gcc" "-fcxx-exceptions" "-fexceptions" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-vectorize-slp" "-o" "01.o" "-x" "c++" "01.cpp"

(no /32 suffix).

and it fails to compile this file:

In file included from test.cpp:2:
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:1405:27: error: __int128 is not supported on this target
     struct numeric_limits<__int128>
                           ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:1409:33: error: __int128 is not supported on this target
       static _GLIBCXX_CONSTEXPR __int128
                                 ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:1412:33: error: __int128 is not supported on this target
       static _GLIBCXX_CONSTEXPR __int128
                                 ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:1421:28: error: __int128 is not supported on this target
        = __glibcxx_digits (__int128);
                            ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:138:11: note: expanded from macro '__glibcxx_digits'
   (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T))
           ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:1421:28: error: __int128 is not supported on this target
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:138:49: note: expanded from macro '__glibcxx_digits'
   (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T))
                                                 ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:128:31: note: expanded from macro '__glibcxx_signed'
#define __glibcxx_signed(T) ((T)(-1) < 0)
                                   ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:1423:30: error: __int128 is not supported on this target
        = __glibcxx_digits10 (__int128);
                              ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:142:22: note: expanded from macro '__glibcxx_digits10'
   (__glibcxx_digits (T) * 643L / 2136)
                      ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:138:11: note: expanded from macro '__glibcxx_digits'
   (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T))
           ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:1423:30: error: __int128 is not supported on this target
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/limits:142:22: note: expanded from macro '__glibcxx_digits10'
   (__glibcxx_digits (T) * 643L / 2136)
....

I fixed this problem for me with attached patch but I'm not sure if it breaks something else (the logic of toolchain selection is complicated). Please check if this fix is right or not.

m32-fix.patch (6.11 KB)

Hi,

I have a problem with current Clang master: it selects x64 headers for
32-bit architecture and it leads to compiler errors.
I have Ubuntu 14.04 with GCC-4.8.2 and 4.6.4 installed + multilib. Clang 3.5
(master) doesn't add "/32" suffixes if "-m32" option is specified.

1. Could you consider to use Phabricator (http://reviews.llvm.org/)
for the patch submitting?
2. Could you add any test case to the patch to reproduce the bug? The
following commit has the driver test case example:
http://llvm.org/viewvc/llvm-project?rev=202873&view=rev
3. Very minor note - there is a typo in the variable name "NewSubling".

Regards,
Simon

Hi,

I have a problem with current Clang master: it selects x64 headers for
32-bit architecture and it leads to compiler errors.
I have Ubuntu 14.04 with GCC-4.8.2 and 4.6.4 installed + multilib. Clang 3.5
(master) doesn't add "/32" suffixes if "-m32" option is specified.

1. Could you consider to use Phabricator (http://reviews.llvm.org/)
for the patch submitting?

Aleksei, please add me to the review when you do.

Hello,

This patch breaks some other tests so I was not sure if it is OK to use Phabricator. But there were some questions to those tests. Anyway, I've created a review.

Example I found in test (linux-ld.c):

//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: --target=i386-unknown-linux -m64 \
// RUN: --sysroot=%S/Inputs/multilib_32bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-32-TO-64 %s
// CHECK-32-TO-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-32-TO-64: "{{.*}}/usr/lib/gcc/i386-unknown-linux/4.6.0/64{{/|\\\\}}crtbegin.o"
// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/64"
// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/lib/../lib64"
// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../lib64"
// CHECK-32-TO-64: "-L[[SYSROOT]]/lib/../lib64"
// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/../lib64"
// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0"
// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../../../i386-unknown-linux/lib"
// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/../../.."
// CHECK-32-TO-64: "-L[[SYSROOT]]/lib"
// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib"

Is it OK to use both "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0" (that has 32-bit object files inside) and "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/4.6.0/64" (that has 64-bit object files)? There are some similar test failures. There were also some failures on MIPS64 tests where I don't know if it is correct or not.

30.04.2014 23:01, Jonathan Roelofs пишет:

Hi,

I have created new revision with updated patch
http://reviews.llvm.org/D3684. Now all tests are passed.

Please check and review it.