diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 54e2f361a9f141..4420f6a2c1c382 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(*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 should not include an X/E around + // . + 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 14550b9e2db935..327a201cdeba16 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 caf06bd5f9f6ef..80311aa320fe58 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::Int<1>); template using matrix1xN = int __attribute__((matrix_type(1, N))); template void test8(matrix1xN 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 4e7707aaeed9c7..70386b87fcee36 100644 --- a/clang/test/CodeGenCXX/enable_if.cpp +++ b/clang/test/CodeGenCXX/enable_if.cpp @@ -5,7 +5,7 @@ int test5(int); template 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