[llvm-branch-commits] [clang] 0b7b698 - Itanium Mangling: In 'enable_if', omit X/E around <expr-primary>.

James Y Knight via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jan 27 17:02:52 PST 2021


Author: James Y Knight
Date: 2021-01-27T20:02:30-05:00
New Revision: 0b7b698fecd37415a635a586e5ca159ab0b8872f

URL: https://github.com/llvm/llvm-project/commit/0b7b698fecd37415a635a586e5ca159ab0b8872f
DIFF: https://github.com/llvm/llvm-project/commit/0b7b698fecd37415a635a586e5ca159ab0b8872f.diff

LOG: Itanium Mangling: In 'enable_if', omit X/E around <expr-primary>.

The Clang enable_if extension is mangled as an <extended-qualifier>,
which is supposed to contain <template-args>. However, we were
unconditionally emitting X/E around its arguments, neglecting the fact
that <expr-primary> should be emitted directly without the surrounding
X/E.

Differential Revision: https://reviews.llvm.org/D95488

(cherry picked from commit a7246ba02a8923f316419a62d836dbe1c0b437bd)

Added: 
    

Modified: 
    clang/lib/AST/ItaniumMangle.cpp
    clang/test/CodeGen/enable_if.c
    clang/test/CodeGenCXX/clang-abi-compat.cpp
    clang/test/CodeGenCXX/enable_if.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 54e2f361a9f1..4420f6a2c1c3 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -727,9 +727,17 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
       EnableIfAttr *EIA = dyn_cast<EnableIfAttr>(*I);
       if (!EIA)
         continue;
-      Out << 'X';
-      mangleExpression(EIA->getCond());
-      Out << 'E';
+      if (Context.getASTContext().getLangOpts().getClangABICompat() >
+          LangOptions::ClangABI::Ver11) {
+        mangleTemplateArgExpr(EIA->getCond());
+      } else {
+        // Prior to Clang 12, we hardcoded the X/E around enable-if's argument,
+        // even though <template-arg> should not include an X/E around
+        // <expr-primary>.
+        Out << 'X';
+        mangleExpression(EIA->getCond());
+        Out << 'E';
+      }
     }
     Out << 'E';
     FunctionTypeDepth.pop(Saved);

diff  --git a/clang/test/CodeGen/enable_if.c b/clang/test/CodeGen/enable_if.c
index 14550b9e2db9..327a201cdeba 100644
--- a/clang/test/CodeGen/enable_if.c
+++ b/clang/test/CodeGen/enable_if.c
@@ -31,22 +31,22 @@ void bar(int m) __attribute__((overloadable, enable_if(m > 0, "")));
 void bar(int m) __attribute__((overloadable, enable_if(1, "")));
 // CHECK-LABEL: define{{.*}} void @test2
 void test2() {
-  // CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi
+  // CHECK: store void (i32)* @_Z3barUa9enable_ifILi1EEi
   void (*p)(int) = bar;
-  // CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi
+  // CHECK: store void (i32)* @_Z3barUa9enable_ifILi1EEi
   void (*p2)(int) = &bar;
-  // CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi
+  // CHECK: store void (i32)* @_Z3barUa9enable_ifILi1EEi
   p = bar;
-  // CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi
+  // CHECK: store void (i32)* @_Z3barUa9enable_ifILi1EEi
   p = &bar;
 
-  // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*)
+  // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifILi1EEi to i8*)
   void *vp1 = (void*)&bar;
-  // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*)
+  // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifILi1EEi to i8*)
   void *vp2 = (void*)bar;
-  // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*)
+  // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifILi1EEi to i8*)
   vp1 = (void*)&bar;
-  // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*)
+  // CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifILi1EEi to i8*)
   vp1 = (void*)bar;
 }
 
@@ -54,13 +54,13 @@ void baz(int m) __attribute__((overloadable, enable_if(1, "")));
 void baz(int m) __attribute__((overloadable));
 // CHECK-LABEL: define{{.*}} void @test3
 void test3() {
-  // CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi
+  // CHECK: store void (i32)* @_Z3bazUa9enable_ifILi1EEi
   void (*p)(int) = baz;
-  // CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi
+  // CHECK: store void (i32)* @_Z3bazUa9enable_ifILi1EEi
   void (*p2)(int) = &baz;
-  // CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi
+  // CHECK: store void (i32)* @_Z3bazUa9enable_ifILi1EEi
   p = baz;
-  // CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi
+  // CHECK: store void (i32)* @_Z3bazUa9enable_ifILi1EEi
   p = &baz;
 }
 
@@ -71,13 +71,13 @@ void qux(int m) __attribute__((overloadable, enable_if(1, ""),
 void qux(int m) __attribute__((overloadable, enable_if(1, "")));
 // CHECK-LABEL: define{{.*}} void @test4
 void test4() {
-  // CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXLi1EEEi
+  // CHECK: store void (i32)* @_Z3quxUa9enable_ifILi1ELi1EEi
   void (*p)(int) = qux;
-  // CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXLi1EEEi
+  // CHECK: store void (i32)* @_Z3quxUa9enable_ifILi1ELi1EEi
   void (*p2)(int) = &qux;
-  // CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXLi1EEEi
+  // CHECK: store void (i32)* @_Z3quxUa9enable_ifILi1ELi1EEi
   p = qux;
-  // CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXLi1EEEi
+  // CHECK: store void (i32)* @_Z3quxUa9enable_ifILi1ELi1EEi
   p = &qux;
 }
 
@@ -90,6 +90,6 @@ void test5() {
   int foo(char *i __attribute__((pass_object_size(0))))
       __attribute__((enable_if(1, ""), overloadable));
 
-  // CHECK: call i32 @_Z3fooUa9enable_ifIXLi1EEEPcU17pass_object_size0
+  // CHECK: call i32 @_Z3fooUa9enable_ifILi1EEPcU17pass_object_size0
   foo((void*)0);
 }

diff  --git a/clang/test/CodeGenCXX/clang-abi-compat.cpp b/clang/test/CodeGenCXX/clang-abi-compat.cpp
index caf06bd5f9f6..80311aa320fe 100644
--- a/clang/test/CodeGenCXX/clang-abi-compat.cpp
+++ b/clang/test/CodeGenCXX/clang-abi-compat.cpp
@@ -130,4 +130,9 @@ template void test7<A>(A::Int<1>);
 template<int N> using matrix1xN = int __attribute__((matrix_type(1, N)));
 template<int N> void test8(matrix1xN<N> a) {}
 template void test8<2>(matrix1xN<2> a);
+
+// PRE12: @_ZN12expr_primary5test9EUa9enable_ifIXLi1EEEv
+// V12:   @_ZN12expr_primary5test9EUa9enable_ifILi1EEv
+void test9(void) __attribute__((enable_if(1, ""))) {}
+
 }

diff  --git a/clang/test/CodeGenCXX/enable_if.cpp b/clang/test/CodeGenCXX/enable_if.cpp
index 4e7707aaeed9..70386b87fcee 100644
--- a/clang/test/CodeGenCXX/enable_if.cpp
+++ b/clang/test/CodeGenCXX/enable_if.cpp
@@ -5,7 +5,7 @@ int test5(int);
 template <typename T>
 T test5(T) __attribute__((enable_if(1, "better than non-template")));
 
-// CHECK: @_Z5test5IiEUa9enable_ifIXLi1EEET_S0_
+// CHECK: @_Z5test5IiEUa9enable_ifILi1EET_S0_
 int (*Ptr)(int) = &test5;
 
 // Test itanium mangling for attribute enable_if


        


More information about the llvm-branch-commits mailing list