ro created this revision.
ro added reviewers: fedor.sergeev, rsmith, mehdi_amini, rnk.
Herald added subscribers: kadircet, jrtc27, ilya-biryukov, mgorny, jyknight.
Herald added a project: clang.

`Builtins-*-sunos :: compiler_rt_logbf_test.c` currently FAILs on Solaris, both 
SPARC and
x86, 32 and 64-bit.

It turned out that this is due to different behaviour of `logb` depending on 
the C
standard compiled for, as documented on `logb(3M)`:

  RETURN VALUES
         Upon successful completion, these functions return the exponent of x.
  
         If x is subnormal:
  
             o      For SUSv3-conforming applications compiled with the c99 com-
                    piler  driver  (see standards(7)), the exponent of x as if x
                    were normalized is returned.
  
             o      Otherwise, if compiled with the cc compiler  driver,  -1022,
                    -126,  and  -16382  are  returned  for  logb(), logbf(), and
                    logbl(), respectively.

Studio c99 and gcc control this by linking with the appropriate version of 
`values-xpg[46].o`, but clang uses neither of those.

The following patch fixes this by following what gcc does, as corrected some 
time ago
in `Fix use of Solaris values-Xc.o (PR target/40411)`, 
https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02350.html and 
https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02384.html.

It makes use of `LangStandard::getLangStandardForName` to parse the `std=<std>`
values.  However, I found that the function currently doesn't handle the alias 
forms
(like `c90` for `c89`).  Given that it isn't currently used in the clang repo, 
I just added
that handling.

As a consequence, `ClangDriverTests` now also needs to be linked with 
`libclangFrontend`.

Tested on `x86_64-pc-solaris2.11`, `sparcv9-sun-solaris2.11`, and 
`x86_64-pc-linux-gnu`.
Ok for trunk (and a backport to the llvm 9 branch)?


Repository:
  rC Clang

https://reviews.llvm.org/D64793

Files:
  lib/Driver/ToolChains/Solaris.cpp
  lib/Frontend/LangStandards.cpp
  test/Driver/Inputs/solaris_sparc_tree/usr/lib/values-Xa.o
  test/Driver/Inputs/solaris_sparc_tree/usr/lib/values-Xc.o
  test/Driver/Inputs/solaris_sparc_tree/usr/lib/values-xpg4.o
  test/Driver/Inputs/solaris_sparc_tree/usr/lib/values-xpg6.o
  test/Driver/Inputs/solaris_x86_tree/usr/lib/values-Xa.o
  test/Driver/Inputs/solaris_x86_tree/usr/lib/values-Xc.o
  test/Driver/Inputs/solaris_x86_tree/usr/lib/values-xpg4.o
  test/Driver/Inputs/solaris_x86_tree/usr/lib/values-xpg6.o
  test/Driver/solaris-ld-values.c
  test/Driver/solaris-ld-values.cpp
  unittests/Driver/CMakeLists.txt

Index: unittests/Driver/CMakeLists.txt
===================================================================
--- unittests/Driver/CMakeLists.txt
+++ unittests/Driver/CMakeLists.txt
@@ -15,4 +15,5 @@
   PRIVATE
   clangDriver
   clangBasic
+  clangFrontend
   )
Index: test/Driver/solaris-ld-values.cpp
===================================================================
--- /dev/null
+++ test/Driver/solaris-ld-values.cpp
@@ -0,0 +1,45 @@
+// General tests that the correct versions of values-*.o are used on
+// Solaris targets sane. Note that we use sysroot to make these tests
+// independent of the host system.
+
+// Check sparc-sun-solaris2.11, 32bit
+// RUN: %clang -no-canonical-prefixes -ansi %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-ANSI %s
+// CHECK-LD-SPARC32-ANSI: values-Xc.o
+// CHECK-LD-SPARC32-ANSI: values-xpg6.o
+
+// RUN: %clang -no-canonical-prefixes -std=c++98 %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-CPP98 %s
+// CHECK-LD-SPARC32-CPP98: values-Xc.o
+// CHECK-LD-SPARC32-CPP98: values-xpg6.o
+
+// RUN: %clang -no-canonical-prefixes -std=c++11 %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-CPP11 %s
+// CHECK-LD-SPARC32-CPP11: values-Xc.o
+// CHECK-LD-SPARC32-CPP11: values-xpg6.o
+
+// RUN: %clang -no-canonical-prefixes -std=gnu++98 %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-GNUPP98 %s
+// CHECK-LD-SPARC32-GNUPP98: values-Xa.o
+// CHECK-LD-SPARC32-GNUPP98: values-xpg6.o
+
+// Check i386-pc-solaris2.11, 32bit
+// RUN: %clang -no-canonical-prefixes -ANSI %s -### -o %t.o 2>&1 \
+// RUN:     --target=i386-pc-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_x86_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-X32-ANSI %s
+// CHECK-LD-X32-ANSI: values-Xa.o
+// CHECK-LD-X32-ANSI: values-xpg6.o
Index: test/Driver/solaris-ld-values.c
===================================================================
--- /dev/null
+++ test/Driver/solaris-ld-values.c
@@ -0,0 +1,77 @@
+// General tests that the correct versions of values-*.o are used on
+// Solaris targets sane. Note that we use sysroot to make these tests
+// independent of the host system.
+
+// Check sparc-sun-solaris2.11, 32bit
+// RUN: %clang -no-canonical-prefixes -ansi %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-ANSI %s
+// CHECK-LD-SPARC32-ANSI: values-Xc.o
+// CHECK-LD-SPARC32-ANSI: values-xpg6.o
+
+// RUN: %clang -no-canonical-prefixes -std=c89 %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-C89 %s
+// CHECK-LD-SPARC32-C89: values-Xc.o
+// CHECK-LD-SPARC32-C89: values-xpg4.o
+
+// RUN: %clang -no-canonical-prefixes -std=c90 %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-C90 %s
+// CHECK-LD-SPARC32-C90: values-Xc.o
+// CHECK-LD-SPARC32-C90: values-xpg4.o
+
+// RUN: %clang -no-canonical-prefixes -std=iso9899:199409 %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-C94 %s
+// CHECK-LD-SPARC32-C94: values-Xc.o
+// CHECK-LD-SPARC32-C94: values-xpg4.o
+
+// RUN: %clang -no-canonical-prefixes -std=c11 %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-C11 %s
+// CHECK-LD-SPARC32-C11: values-Xc.o
+// CHECK-LD-SPARC32-C11: values-xpg6.o
+
+// RUN: %clang -no-canonical-prefixes -std=gnu89 %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-GNU89 %s
+// CHECK-LD-SPARC32-GNU89: values-Xa.o
+// CHECK-LD-SPARC32-GNU89: values-xpg4.o
+
+// RUN: %clang -no-canonical-prefixes -std=gnu90 %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-GNU90 %s
+// CHECK-LD-SPARC32-GNU90: values-Xa.o
+// CHECK-LD-SPARC32-GNU90: values-xpg4.o
+
+// RUN: %clang -no-canonical-prefixes -std=gnu11 %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-sun-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_sparc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-SPARC32-GNU11 %s
+// CHECK-LD-SPARC32-GNU11: values-Xa.o
+// CHECK-LD-SPARC32-GNU11: values-xpg6.o
+
+// Check i386-pc-solaris2.11, 32bit
+// RUN: %clang -no-canonical-prefixes -ansi %s -### -o %t.o 2>&1 \
+// RUN:     --target=i386-pc-solaris2.11 \
+// RUN:     --gcc-toolchain="" \
+// RUN:     --sysroot=%S/Inputs/solaris_x86_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-X32-ANSI %s
+// CHECK-LD-X32-ANSI: values-Xc.o
+// CHECK-LD-X32-ANSI: values-xpg6.o
Index: lib/Frontend/LangStandards.cpp
===================================================================
--- lib/Frontend/LangStandards.cpp
+++ lib/Frontend/LangStandards.cpp
@@ -31,6 +31,8 @@
   Kind K = llvm::StringSwitch<Kind>(Name)
 #define LANGSTANDARD(id, name, lang, desc, features) \
     .Case(name, lang_##id)
+#define LANGSTANDARD_ALIAS(id, alias) \
+    .Case(alias, lang_##id)
 #include "clang/Frontend/LangStandards.def"
     .Default(lang_unspecified);
   if (K == lang_unspecified)
Index: lib/Driver/ToolChains/Solaris.cpp
===================================================================
--- lib/Driver/ToolChains/Solaris.cpp
+++ lib/Driver/ToolChains/Solaris.cpp
@@ -13,6 +13,7 @@
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
+#include "clang/Frontend/LangStandard.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -20,6 +21,7 @@
 using namespace clang::driver;
 using namespace clang::driver::tools;
 using namespace clang::driver::toolchains;
+using namespace clang::frontend;
 using namespace clang;
 using namespace llvm::opt;
 
@@ -86,8 +88,28 @@
           Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
 
     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
+
+    const Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi);
+    bool HaveAnsi = false;
+    const LangStandard *LangStd = nullptr;
+    if (Std) {
+      HaveAnsi = Std->getOption().matches(options::OPT_ansi);
+      if (!HaveAnsi)
+        LangStd = LangStandard::getLangStandardForName(Std->getValue());
+    }
+
+    const char *values_X = "values-Xa.o";
+    // Use values-Xc.o for -ansi, -std=c*, -std=iso9899:199409.
+    if (HaveAnsi || (LangStd && !LangStd->isGNUMode()))
+      values_X = "values-Xc.o";
+    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(values_X)));
+
+    const char *values_xpg = "values-xpg6.o";
+    // Use values-xpg4.o for -std=c90, -std=gnu90, -std=iso9899:199409.
+    if (LangStd && LangStd->getLanguage() == InputKind::C && !LangStd->isC99())
+      values_xpg = "values-xpg4.o";
     CmdArgs.push_back(
-        Args.MakeArgString(getToolChain().GetFilePath("values-Xa.o")));
+        Args.MakeArgString(getToolChain().GetFilePath(values_xpg)));
     CmdArgs.push_back(
         Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to