<div dir="ltr">Hi Hans,<div><br></div><div>We should get this into Clang 5 so that people can opt out of the ABI bugfix for passing C++ class types by value.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 25 August 2017 at 18:04, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Fri Aug 25 18:04:35 2017<br>
New Revision: 311823<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=311823&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=311823&view=rev</a><br>
Log:<br>
Add flag to request Clang is ABI-compatible with older versions of itself<br>
<br>
This patch adds a flag -fclang-abi-compat that can be used to request that<br>
Clang attempts to be ABI-compatible with some older version of itself.<br>
<br>
This is provided on a best-effort basis; right now, this can be used to undo<br>
the ABI change in r310401, reverting Clang to its prior C++ ABI for pass/return<br>
by value of class types affected by that change, and to undo the ABI change in<br>
r262688, reverting Clang to using integer registers rather than SSE registers<br>
for passing <1 x long long> vectors. The intent is that we will maintain this<br>
backwards compatibility path as we make ABI-breaking fixes in future.<br>
<br>
The reversion to the old behavior for r310401 is also applied to the PS4 target<br>
since that change is not part of its platform ABI (which is essentially to do<br>
whatever Clang 3.2 did).<br>
<br>
Added:<br>
    cfe/trunk/test/CodeGenCXX/<wbr>clang-abi-compat.cpp<br>
    cfe/trunk/test/Frontend/clang-<wbr>abi-compat.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/<wbr>Driver/Options.td<br>
    cfe/trunk/include/clang/<wbr>Frontend/CodeGenOptions.def<br>
    cfe/trunk/include/clang/<wbr>Frontend/CodeGenOptions.h<br>
    cfe/trunk/lib/CodeGen/ABIInfo.<wbr>h<br>
    cfe/trunk/lib/CodeGen/<wbr>CodeGenTypes.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>CodeGenTypes.h<br>
    cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>TargetInfo.cpp<br>
    cfe/trunk/lib/Driver/<wbr>ToolChains/Clang.cpp<br>
    cfe/trunk/lib/Frontend/<wbr>CompilerInvocation.cpp<br>
    cfe/trunk/test/CodeGenCXX/<wbr>uncopyable-args.cpp<br>
    cfe/trunk/test/Driver/flags.c<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Driver/Options.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Driver/Options.td?rev=<wbr>311823&r1=311822&r2=311823&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Driver/Options.td (original)<br>
+++ cfe/trunk/include/clang/<wbr>Driver/Options.td Fri Aug 25 18:04:35 2017<br>
@@ -711,6 +711,9 @@ def fbuiltin : Flag<["-"], "fbuiltin">,<br>
 def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group<f_Group>,<br>
   Flags<[DriverOption]>, HelpText<"Load the clang builtins module map file.">;<br>
 def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>;<br>
+def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group<f_clang_Group>,<br>
+  Flags<[CC1Option]>, MetaVarName<"<version>">, Values<"<major>.<minor>,<wbr>latest">,<br>
+  HelpText<"Attempt to match the ABI of Clang <version>">;<br>
 def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;<br>
 def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,<br>
   Flags<[CoreOption, CC1Option]>, HelpText<"Use colors in diagnostics">;<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Frontend/CodeGenOptions.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Frontend/CodeGenOptions.<wbr>def?rev=311823&r1=311822&r2=<wbr>311823&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Frontend/CodeGenOptions.def (original)<br>
+++ cfe/trunk/include/clang/<wbr>Frontend/CodeGenOptions.def Fri Aug 25 18:04:35 2017<br>
@@ -120,6 +120,10 @@ CODEGENOPT(<wbr>NoZeroInitializedInBSS , 1, 0<br>
 ENUM_CODEGENOPT(<wbr>ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)<br>
 CODEGENOPT(<wbr>OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is<br>
                                         ///< enabled.<br>
+<br>
+/// A version of Clang that we should attempt to be ABI-compatible with.<br>
+ENUM_CODEGENOPT(<wbr>ClangABICompat, ClangABI, 4, ClangABI::Latest)<br>
+<br>
 VALUE_CODEGENOPT(<wbr>OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.<br>
 VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.<br>
<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Frontend/CodeGenOptions.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.h?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Frontend/CodeGenOptions.<wbr>h?rev=311823&r1=311822&r2=<wbr>311823&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Frontend/CodeGenOptions.h (original)<br>
+++ cfe/trunk/include/clang/<wbr>Frontend/CodeGenOptions.h Fri Aug 25 18:04:35 2017<br>
@@ -69,6 +69,23 @@ public:<br>
     LocalExecTLSModel<br>
   };<br>
<br>
+  /// Clang versions with different platform ABI conformance.<br>
+  enum class ClangABI {<br>
+    /// Attempt to be ABI-compatible with code generated by Clang 3.8.x<br>
+    /// (SVN r257626). This causes <1 x long long> to be passed in an<br>
+    /// integer register instead of an SSE register on x64_64.<br>
+    Ver3_8,<br>
+<br>
+    /// Attempt to be ABI-compatible with code generated by Clang 4.0.x<br>
+    /// (SVN r291814). This causes move operations to be ignored when<br>
+    /// determining whether a class type can be passed or returned directly.<br>
+    Ver4,<br>
+<br>
+    /// Conform to the underlying platform's C and C++ ABIs as closely<br>
+    /// as we can.<br>
+    Latest<br>
+  };<br>
+<br>
   enum StructReturnConventionKind {<br>
     SRCK_Default,  // No special option was passed.<br>
     SRCK_OnStack,  // Small structs on the stack (-fpcc-struct-return).<br>
<br>
Modified: cfe/trunk/lib/CodeGen/ABIInfo.<wbr>h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ABIInfo.h?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>ABIInfo.h?rev=311823&r1=<wbr>311822&r2=311823&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/ABIInfo.<wbr>h (original)<br>
+++ cfe/trunk/lib/CodeGen/ABIInfo.<wbr>h Fri Aug 25 18:04:35 2017<br>
@@ -24,6 +24,7 @@ namespace llvm {<br>
<br>
 namespace clang {<br>
   class ASTContext;<br>
+  class CodeGenOptions;<br>
   class TargetInfo;<br>
<br>
 namespace CodeGen {<br>
@@ -68,6 +69,7 @@ namespace swiftcall {<br>
     llvm::LLVMContext &getVMContext() const;<br>
     const llvm::DataLayout &getDataLayout() const;<br>
     const TargetInfo &getTarget() const;<br>
+    const CodeGenOptions &getCodeGenOpts() const;<br>
<br>
     /// Return the calling convention to use for system runtime<br>
     /// functions.<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>CodeGenTypes.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CodeGenTypes.cpp?rev=311823&<wbr>r1=311822&r2=311823&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>CodeGenTypes.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>CodeGenTypes.cpp Fri Aug 25 18:04:35 2017<br>
@@ -44,6 +44,10 @@ CodeGenTypes::~CodeGenTypes() {<br>
     delete &*I++;<br>
 }<br>
<br>
+const CodeGenOptions &CodeGenTypes::getCodeGenOpts(<wbr>) const {<br>
+  return CGM.getCodeGenOpts();<br>
+}<br>
+<br>
 void CodeGenTypes::<wbr>addRecordTypeName(const RecordDecl *RD,<br>
                                      llvm::StructType *Ty,<br>
                                      StringRef suffix) {<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>CodeGenTypes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.h?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CodeGenTypes.h?rev=311823&r1=<wbr>311822&r2=311823&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>CodeGenTypes.h (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>CodeGenTypes.h Fri Aug 25 18:04:35 2017<br>
@@ -178,6 +178,7 @@ public:<br>
   const TargetInfo &getTarget() const { return Target; }<br>
   CGCXXABI &getCXXABI() const { return TheCXXABI; }<br>
   llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); }<br>
+  const CodeGenOptions &getCodeGenOpts() const;<br>
<br>
   /// ConvertType - Convert type T into a llvm::Type.<br>
   llvm::Type *ConvertType(QualType T);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp?rev=311823&<wbr>r1=311822&r2=311823&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp Fri Aug 25 18:04:35 2017<br>
@@ -62,9 +62,20 @@ public:<br>
<br>
   bool classifyReturnType(<wbr>CGFunctionInfo &FI) const override;<br>
<br>
+  bool passClassIndirect(const CXXRecordDecl *RD) const {<br>
+    // Clang <= 4 used the pre-C++11 rule, which ignores move operations.<br>
+    // The PS4 platform ABI follows the behavior of Clang 3.2.<br>
+    if (CGM.getCodeGenOpts().<wbr>getClangABICompat() <=<br>
+            CodeGenOptions::ClangABI::Ver4 ||<br>
+        CGM.getTriple().getOS() == llvm::Triple::PS4)<br>
+      return RD->hasNonTrivialDestructor() ||<br>
+             RD-><wbr>hasNonTrivialCopyConstructor()<wbr>;<br>
+    return !canCopyArgument(RD);<br>
+  }<br>
+<br>
   RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {<br>
     // If C++ prohibits us from making a copy, pass by address.<br>
-    if (!canCopyArgument(RD))<br>
+    if (passClassIndirect(RD))<br>
       return RAA_Indirect;<br>
     return RAA_Default;<br>
   }<br>
@@ -1012,7 +1023,7 @@ bool ItaniumCXXABI::<wbr>classifyReturnType(C<br>
     return false;<br>
<br>
   // If C++ prohibits us from making a copy, return by address.<br>
-  if (!canCopyArgument(RD)) {<br>
+  if (passClassIndirect(RD)) {<br>
     auto Align = CGM.getContext().<wbr>getTypeAlignInChars(FI.<wbr>getReturnType());<br>
     FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);<br>
     return true;<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>TargetInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>TargetInfo.cpp?rev=311823&r1=<wbr>311822&r2=311823&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>TargetInfo.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>TargetInfo.cpp Fri Aug 25 18:04:35 2017<br>
@@ -184,7 +184,11 @@ const TargetInfo &ABIInfo::getTarget() c<br>
   return CGT.getTarget();<br>
 }<br>
<br>
-bool ABIInfo:: isAndroid() const { return getTarget().getTriple().<wbr>isAndroid(); }<br>
+const CodeGenOptions &ABIInfo::getCodeGenOpts() const {<br>
+  return CGT.getCodeGenOpts();<br>
+}<br>
+<br>
+bool ABIInfo::isAndroid() const { return getTarget().getTriple().<wbr>isAndroid(); }<br>
<br>
 bool ABIInfo::<wbr>isHomogeneousAggregateBaseType<wbr>(QualType Ty) const {<br>
   return false;<br>
@@ -2112,9 +2116,14 @@ class X86_64ABIInfo : public SwiftABIInf<br>
     return !getTarget().getTriple().<wbr>isOSDarwin();<br>
   }<br>
<br>
-  /// GCC classifies <1 x long long> as SSE but compatibility with older clang<br>
-  // compilers require us to classify it as INTEGER.<br>
+  /// GCC classifies <1 x long long> as SSE but some platform ABIs choose to<br>
+  /// classify it as INTEGER (for compatibility with older clang compilers).<br>
   bool classifyIntegerMMXAsSSE() const {<br>
+    // Clang <= 3.8 did not do this.<br>
+    if (getCodeGenOpts().<wbr>getClangABICompat() <=<br>
+        CodeGenOptions::ClangABI::<wbr>Ver3_8)<br>
+      return false;<br>
+<br>
     const llvm::Triple &Triple = getTarget().getTriple();<br>
     if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::PS4)<br>
       return false;<br>
<br>
Modified: cfe/trunk/lib/Driver/<wbr>ToolChains/Clang.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Driver/<wbr>ToolChains/Clang.cpp?rev=<wbr>311823&r1=311822&r2=311823&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Driver/<wbr>ToolChains/Clang.cpp (original)<br>
+++ cfe/trunk/lib/Driver/<wbr>ToolChains/Clang.cpp Fri Aug 25 18:04:35 2017<br>
@@ -2933,6 +2933,9 @@ void Clang::ConstructJob(<wbr>Compilation &C,<br>
<br>
   addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);<br>
<br>
+  if (auto *ABICompatArg = Args.getLastArg(options::OPT_<wbr>fclang_abi_compat_EQ))<br>
+    ABICompatArg->render(Args, CmdArgs);<br>
+<br>
   // Add runtime flag for PS4 when PGO or Coverage are enabled.<br>
   if (getToolChain().getTriple().<wbr>isPS4CPU())<br>
     PS4cpu::addProfileRTArgs(<wbr>getToolChain(), Args, CmdArgs);<br>
<br>
Modified: cfe/trunk/lib/Frontend/<wbr>CompilerInvocation.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Frontend/CompilerInvocation.<wbr>cpp?rev=311823&r1=311822&r2=<wbr>311823&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Frontend/<wbr>CompilerInvocation.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/<wbr>CompilerInvocation.cpp Fri Aug 25 18:04:35 2017<br>
@@ -573,6 +573,33 @@ static bool ParseCodeGenArgs(CodeGenOpti<br>
   if (!Opts.<wbr>ProfileInstrumentUsePath.<wbr>empty())<br>
     setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath)<wbr>;<br>
<br>
+  if (Arg *A = Args.getLastArg(OPT_fclang_<wbr>abi_compat_EQ)) {<br>
+    Opts.setClangABICompat(<wbr>CodeGenOptions::ClangABI::<wbr>Latest);<br>
+<br>
+    StringRef Ver = A->getValue();<br>
+    std::pair<StringRef, StringRef> VerParts = Ver.split('.');<br>
+    unsigned Major, Minor = 0;<br>
+<br>
+    // Check the version number is valid: either 3.x (0 <= x <= 9) or<br>
+    // y or y.0 (4 <= y <= current version).<br>
+    if (!VerParts.first.startswith("<wbr>0") &&<br>
+        !VerParts.first.getAsInteger(<wbr>10, Major) &&<br>
+        3 <= Major && Major <= CLANG_VERSION_MAJOR &&<br>
+        (Major == 3 ? VerParts.second.size() == 1 &&<br>
+                      !VerParts.second.getAsInteger(<wbr>10, Minor)<br>
+                    : VerParts.first.size() == Ver.size() ||<br>
+                      VerParts.second == "0")) {<br>
+      // Got a valid version number.<br>
+      if (Major == 3 && Minor <= 8)<br>
+        Opts.setClangABICompat(<wbr>CodeGenOptions::ClangABI::<wbr>Ver3_8);<br>
+      else if (Major <= 4)<br>
+        Opts.setClangABICompat(<wbr>CodeGenOptions::ClangABI::<wbr>Ver4);<br>
+    } else if (Ver != "latest") {<br>
+      Diags.Report(diag::err_drv_<wbr>invalid_value)<br>
+          << A->getAsString(Args) << A->getValue();<br>
+    }<br>
+  }<br>
+<br>
   Opts.CoverageMapping =<br>
       Args.hasFlag(OPT_fcoverage_<wbr>mapping, OPT_fno_coverage_mapping, false);<br>
   Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_<wbr>mapping);<br>
<br>
Added: cfe/trunk/test/CodeGenCXX/<wbr>clang-abi-compat.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/clang-abi-compat.cpp?rev=311823&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>CodeGenCXX/clang-abi-compat.<wbr>cpp?rev=311823&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/<wbr>clang-abi-compat.cpp (added)<br>
+++ cfe/trunk/test/CodeGenCXX/<wbr>clang-abi-compat.cpp Fri Aug 25 18:04:35 2017<br>
@@ -0,0 +1,19 @@<br>
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.0 %s -emit-llvm -o - | FileCheck --check-prefix=PRE39 --check-prefix=PRE5 %s<br>
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.8 %s -emit-llvm -o - | FileCheck --check-prefix=PRE39 --check-prefix=PRE5 %s<br>
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.9 %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=PRE5 %s<br>
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=4.0 %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=PRE5 %s<br>
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=5 %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=V5 %s<br>
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=latest %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=V5 %s<br>
+<br>
+typedef __attribute__((vector_size(8))<wbr>) long long v1xi64;<br>
+void clang39(v1xi64) {}<br>
+// PRE39: @_Z7clang39Dv1_x(i64<br>
+// V39: @_Z7clang39Dv1_x(double<br>
+<br>
+struct A {<br>
+  A(const A&) = default;<br>
+  A(A&&);<br>
+};<br>
+void clang5(A) {}<br>
+// PRE5: @_Z6clang51A()<br>
+// V5: @_Z6clang51A(%{{.*}}*<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/<wbr>uncopyable-args.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/uncopyable-args.cpp?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>CodeGenCXX/uncopyable-args.<wbr>cpp?rev=311823&r1=311822&r2=<wbr>311823&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/<wbr>uncopyable-args.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/<wbr>uncopyable-args.cpp Fri Aug 25 18:04:35 2017<br>
@@ -1,4 +1,6 @@<br>
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s<br>
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=NEWABI<br>
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI<br>
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-scei-ps4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI<br>
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=18 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-18<br>
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=19 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-19<br>
<br>
@@ -56,8 +58,10 @@ void bar() {<br>
 // CHECK-LABEL: define void @_ZN9move_ctor3barEv()<br>
 // CHECK: call void @_Z{{.*}}C1Ev(<br>
 // CHECK-NOT: call<br>
-// CHECK: call void @_ZN9move_ctor3fooENS_1AE(%"<wbr>struct.move_ctor::A"* %{{.*}})<br>
-// CHECK-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(%"<wbr>struct.move_ctor::A"*)<br>
+// NEWABI: call void @_ZN9move_ctor3fooENS_1AE(%"<wbr>struct.move_ctor::A"* %{{.*}})<br>
+// OLDABI: call void @_ZN9move_ctor3fooENS_1AE(i8* %{{.*}})<br>
+// NEWABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(%"<wbr>struct.move_ctor::A"*)<br>
+// OLDABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(i8*)<br>
<br>
 // WIN64-LABEL: declare void @"\01?foo@move_ctor@@YAXUA@1@@<wbr>Z"(%"struct.move_ctor::A"*)<br>
 }<br>
@@ -76,8 +80,10 @@ void bar() {<br>
 // CHECK-LABEL: define void @_ZN11all_deleted3barEv()<br>
 // CHECK: call void @_Z{{.*}}C1Ev(<br>
 // CHECK-NOT: call<br>
-// CHECK: call void @_ZN11all_deleted3fooENS_1AE(%<wbr>"struct.all_deleted::A"* %{{.*}})<br>
-// CHECK-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%<wbr>"struct.all_deleted::A"*)<br>
+// NEWABI: call void @_ZN11all_deleted3fooENS_1AE(%<wbr>"struct.all_deleted::A"* %{{.*}})<br>
+// OLDABI: call void @_ZN11all_deleted3fooENS_1AE(<wbr>i8* %{{.*}})<br>
+// NEWABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%<wbr>"struct.all_deleted::A"*)<br>
+// OLDABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(<wbr>i8*)<br>
<br>
 // WIN64-LABEL: declare void @"\01?foo@all_deleted@@YAXUA@1<wbr>@@Z"(%"struct.all_deleted::A"*<wbr>)<br>
 }<br>
@@ -95,8 +101,10 @@ void bar() {<br>
 // CHECK-LABEL: define void @_ZN18implicitly_<wbr>deleted3barEv()<br>
 // CHECK: call void @_Z{{.*}}C1Ev(<br>
 // CHECK-NOT: call<br>
-// CHECK: call void @_ZN18implicitly_<wbr>deleted3fooENS_1AE(%"struct.<wbr>implicitly_deleted::A"* %{{.*}})<br>
-// CHECK-LABEL: declare void @_ZN18implicitly_<wbr>deleted3fooENS_1AE(%"struct.<wbr>implicitly_deleted::A"*)<br>
+// NEWABI: call void @_ZN18implicitly_<wbr>deleted3fooENS_1AE(%"struct.<wbr>implicitly_deleted::A"* %{{.*}})<br>
+// OLDABI: call void @_ZN18implicitly_<wbr>deleted3fooENS_1AE(i8* %{{.*}})<br>
+// NEWABI-LABEL: declare void @_ZN18implicitly_<wbr>deleted3fooENS_1AE(%"struct.<wbr>implicitly_deleted::A"*)<br>
+// OLDABI-LABEL: declare void @_ZN18implicitly_<wbr>deleted3fooENS_1AE(i8*)<br>
<br>
 // In MSVC 2013, the copy ctor is not deleted by a move assignment. In MSVC 2015, it is.<br>
 // WIN64-18-LABEL: declare void @"\01?foo@implicitly_deleted@@<wbr>YAXUA@1@@Z"(i64<br>
@@ -116,8 +124,10 @@ void bar() {<br>
 // CHECK-LABEL: define void @_ZN11one_deleted3barEv()<br>
 // CHECK: call void @_Z{{.*}}C1Ev(<br>
 // CHECK-NOT: call<br>
-// CHECK: call void @_ZN11one_deleted3fooENS_1AE(%<wbr>"struct.one_deleted::A"* %{{.*}})<br>
-// CHECK-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%<wbr>"struct.one_deleted::A"*)<br>
+// NEWABI: call void @_ZN11one_deleted3fooENS_1AE(%<wbr>"struct.one_deleted::A"* %{{.*}})<br>
+// OLDABI: call void @_ZN11one_deleted3fooENS_1AE(<wbr>i8* %{{.*}})<br>
+// NEWABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%<wbr>"struct.one_deleted::A"*)<br>
+// OLDABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(<wbr>i8*)<br>
<br>
 // WIN64-LABEL: declare void @"\01?foo@one_deleted@@YAXUA@1<wbr>@@Z"(%"struct.one_deleted::A"*<wbr>)<br>
 }<br>
@@ -196,8 +206,10 @@ void bar() {<br>
 }<br>
 // CHECK-LABEL: define void @_ZN14two_copy_ctors3barEv()<br>
 // CHECK: call void @_Z{{.*}}C1Ev(<br>
-// CHECK: call void @_ZN14two_copy_ctors3fooENS_<wbr>1BE(%"struct.two_copy_ctors::<wbr>B"* %{{.*}})<br>
-// CHECK-LABEL: declare void @_ZN14two_copy_ctors3fooENS_<wbr>1BE(%"struct.two_copy_ctors::<wbr>B"*)<br>
+// NEWABI: call void @_ZN14two_copy_ctors3fooENS_<wbr>1BE(%"struct.two_copy_ctors::<wbr>B"* %{{.*}})<br>
+// OLDABI: call void @_ZN14two_copy_ctors3fooENS_<wbr>1BE(%"struct.two_copy_ctors::<wbr>B"* byval<br>
+// NEWABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_<wbr>1BE(%"struct.two_copy_ctors::<wbr>B"*)<br>
+// OLDABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_<wbr>1BE(%"struct.two_copy_ctors::<wbr>B"* byval<br>
<br>
 // WIN64-LABEL: declare void @"\01?foo@two_copy_ctors@@<wbr>YAXUB@1@@Z"(%"struct.two_copy_<wbr>ctors::B"*)<br>
 }<br>
@@ -209,7 +221,8 @@ struct A {<br>
   void *p;<br>
 };<br>
 void *foo(A a) { return a.p; }<br>
-// CHECK-LABEL: define i8* @_ZN15definition_only3fooENS_<wbr>1AE(%"struct.definition_only::<wbr>A"*<br>
+// NEWABI-LABEL: define i8* @_ZN15definition_only3fooENS_<wbr>1AE(%"struct.definition_only::<wbr>A"*<br>
+// OLDABI-LABEL: define i8* @_ZN15definition_only3fooENS_<wbr>1AE(i8*<br>
 // WIN64-LABEL: define i8* @"\01?foo@definition_only@@<wbr>YAPEAXUA@1@@Z"(%"struct.<wbr>definition_only::A"*<br>
 }<br>
<br>
@@ -224,7 +237,8 @@ struct A {<br>
   B b;<br>
 };<br>
 void *foo(A a) { return a.b.p; }<br>
-// CHECK-LABEL: define i8* @_ZN17deleted_by_<wbr>member3fooENS_1AE(%"struct.<wbr>deleted_by_member::A"*<br>
+// NEWABI-LABEL: define i8* @_ZN17deleted_by_<wbr>member3fooENS_1AE(%"struct.<wbr>deleted_by_member::A"*<br>
+// OLDABI-LABEL: define i8* @_ZN17deleted_by_<wbr>member3fooENS_1AE(i8*<br>
 // WIN64-LABEL: define i8* @"\01?foo@deleted_by_member@@<wbr>YAPEAXUA@1@@Z"(%"struct.<wbr>deleted_by_member::A"*<br>
 }<br>
<br>
@@ -238,7 +252,8 @@ struct A : B {<br>
   A();<br>
 };<br>
 void *foo(A a) { return a.p; }<br>
-// CHECK-LABEL: define i8* @_ZN15deleted_by_base3fooENS_<wbr>1AE(%"struct.deleted_by_base::<wbr>A"*<br>
+// NEWABI-LABEL: define i8* @_ZN15deleted_by_base3fooENS_<wbr>1AE(%"struct.deleted_by_base::<wbr>A"*<br>
+// OLDABI-LABEL: define i8* @_ZN15deleted_by_base3fooENS_<wbr>1AE(i8*<br>
 // WIN64-LABEL: define i8* @"\01?foo@deleted_by_base@@<wbr>YAPEAXUA@1@@Z"(%"struct.<wbr>deleted_by_base::A"*<br>
 }<br>
<br>
@@ -253,7 +268,8 @@ struct A {<br>
   B b;<br>
 };<br>
 void *foo(A a) { return a.b.p; }<br>
-// CHECK-LABEL: define i8* @_ZN22deleted_by_member_<wbr>copy3fooENS_1AE(%"struct.<wbr>deleted_by_member_copy::A"*<br>
+// NEWABI-LABEL: define i8* @_ZN22deleted_by_member_<wbr>copy3fooENS_1AE(%"struct.<wbr>deleted_by_member_copy::A"*<br>
+// OLDABI-LABEL: define i8* @_ZN22deleted_by_member_<wbr>copy3fooENS_1AE(i8*<br>
 // WIN64-LABEL: define i8* @"\01?foo@deleted_by_member_<wbr>copy@@YAPEAXUA@1@@Z"(%"struct.<wbr>deleted_by_member_copy::A"*<br>
 }<br>
<br>
@@ -267,7 +283,8 @@ struct A : B {<br>
   A();<br>
 };<br>
 void *foo(A a) { return a.p; }<br>
-// CHECK-LABEL: define i8* @_ZN20deleted_by_base_<wbr>copy3fooENS_1AE(%"struct.<wbr>deleted_by_base_copy::A"*<br>
+// NEWABI-LABEL: define i8* @_ZN20deleted_by_base_<wbr>copy3fooENS_1AE(%"struct.<wbr>deleted_by_base_copy::A"*<br>
+// OLDABI-LABEL: define i8* @_ZN20deleted_by_base_<wbr>copy3fooENS_1AE(i8*<br>
 // WIN64-LABEL: define i8* @"\01?foo@deleted_by_base_copy<wbr>@@YAPEAXUA@1@@Z"(%"struct.<wbr>deleted_by_base_copy::A"*<br>
 }<br>
<br>
@@ -277,7 +294,8 @@ struct A {<br>
   A(const A &o) = delete;<br>
   void *p;<br>
 };<br>
-// CHECK-LABEL: define i8* @_ZN15explicit_delete3fooENS_<wbr>1AE(%"struct.explicit_delete::<wbr>A"*<br>
+// NEWABI-LABEL: define i8* @_ZN15explicit_delete3fooENS_<wbr>1AE(%"struct.explicit_delete::<wbr>A"*<br>
+// OLDABI-LABEL: define i8* @_ZN15explicit_delete3fooENS_<wbr>1AE(i8*<br>
 // WIN64-LABEL: define i8* @"\01?foo@explicit_delete@@<wbr>YAPEAXUA@1@@Z"(%"struct.<wbr>explicit_delete::A"*<br>
 void *foo(A a) { return a.p; }<br>
 }<br>
@@ -289,7 +307,8 @@ struct A {<br>
   // Deleted copy ctor due to rvalue ref member.<br>
   int &&ref;<br>
 };<br>
-// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_<wbr>ctor3fooENS_1AE(%"struct.<wbr>implicitly_deleted_copy_ctor::<wbr>A"*<br>
+// NEWABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_<wbr>ctor3fooENS_1AE(%"struct.<wbr>implicitly_deleted_copy_ctor::<wbr>A"*<br>
+// OLDABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_<wbr>ctor3fooENS_1AE(i32*<br>
 // WIN64-LABEL: define {{.*}} @"\01?foo@implicitly_deleted_<wbr>copy_ctor@@YAAEAHUA@1@@Z"(%"<wbr>struct.implicitly_deleted_<wbr>copy_ctor::A"*<br>
 int &foo(A a) { return a.ref; }<br>
<br>
<br>
Modified: cfe/trunk/test/Driver/flags.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/flags.c?rev=311823&r1=311822&r2=311823&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Driver/<wbr>flags.c?rev=311823&r1=311822&<wbr>r2=311823&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Driver/flags.c (original)<br>
+++ cfe/trunk/test/Driver/flags.c Fri Aug 25 18:04:35 2017<br>
@@ -24,3 +24,6 @@<br>
<br>
 // RUN: %clang -target armv7-apple-darwin10 -### -S -mno-implicit-float -mimplicit-float %s 2>&1 | FileCheck -check-prefix=TEST8 %s<br>
 // TEST8-NOT: "-no-implicit-float"<br>
+<br>
+// RUN: %clang -target x86_64-linux-gnu -### -c -fclang-abi-compat=3.2 %s 2>&1 | FileCheck -check-prefix=TEST9 %s<br>
+// TEST9: "-fclang-abi-compat=3.2"<br>
<br>
Added: cfe/trunk/test/Frontend/clang-<wbr>abi-compat.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/clang-abi-compat.cpp?rev=311823&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>Frontend/clang-abi-compat.cpp?<wbr>rev=311823&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Frontend/clang-<wbr>abi-compat.cpp (added)<br>
+++ cfe/trunk/test/Frontend/clang-<wbr>abi-compat.cpp Fri Aug 25 18:04:35 2017<br>
@@ -0,0 +1,15 @@<br>
+// RUN: not %clang_cc1 -fclang-abi-compat=banana %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s<br>
+// RUN: not %clang_cc1 -fclang-abi-compat=2.9 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s<br>
+// RUN: not %clang_cc1 -fclang-abi-compat=8 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s<br>
+// RUN: not %clang_cc1 -fclang-abi-compat=3.10 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s<br>
+// RUN: not %clang_cc1 -fclang-abi-compat=4.1 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s<br>
+// RUN: not %clang_cc1 -fclang-abi-compat=04 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s<br>
+// RUN: not %clang_cc1 -fclang-abi-compat=4. %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s<br>
+// RUN: not %clang_cc1 -fclang-abi-compat=4.00 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s<br>
+// INVALID: error: invalid value '{{.*}}' in '-fclang-abi-compat={{.*}}'<br>
+//<br>
+// RUN: %clang_cc1 -fclang-abi-compat=3.0 %s -fsyntax-only<br>
+// RUN: %clang_cc1 -fclang-abi-compat=3.9 %s -fsyntax-only<br>
+// RUN: %clang_cc1 -fclang-abi-compat=4 %s -fsyntax-only<br>
+// RUN: %clang_cc1 -fclang-abi-compat=4.0 %s -fsyntax-only<br>
+// RUN: %clang_cc1 -fclang-abi-compat=latest %s -fsyntax-only<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>