Skip to content

Commit 0b7b698

Browse files
committed
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 a7246ba)
1 parent 7da92af commit 0b7b698

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -727,9 +727,17 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
727727
EnableIfAttr *EIA = dyn_cast<EnableIfAttr>(*I);
728728
if (!EIA)
729729
continue;
730-
Out << 'X';
731-
mangleExpression(EIA->getCond());
732-
Out << 'E';
730+
if (Context.getASTContext().getLangOpts().getClangABICompat() >
731+
LangOptions::ClangABI::Ver11) {
732+
mangleTemplateArgExpr(EIA->getCond());
733+
} else {
734+
// Prior to Clang 12, we hardcoded the X/E around enable-if's argument,
735+
// even though <template-arg> should not include an X/E around
736+
// <expr-primary>.
737+
Out << 'X';
738+
mangleExpression(EIA->getCond());
739+
Out << 'E';
740+
}
733741
}
734742
Out << 'E';
735743
FunctionTypeDepth.pop(Saved);

clang/test/CodeGen/enable_if.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,36 +31,36 @@ void bar(int m) __attribute__((overloadable, enable_if(m > 0, "")));
3131
void bar(int m) __attribute__((overloadable, enable_if(1, "")));
3232
// CHECK-LABEL: define{{.*}} void @test2
3333
void test2() {
34-
// CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi
34+
// CHECK: store void (i32)* @_Z3barUa9enable_ifILi1EEi
3535
void (*p)(int) = bar;
36-
// CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi
36+
// CHECK: store void (i32)* @_Z3barUa9enable_ifILi1EEi
3737
void (*p2)(int) = &bar;
38-
// CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi
38+
// CHECK: store void (i32)* @_Z3barUa9enable_ifILi1EEi
3939
p = bar;
40-
// CHECK: store void (i32)* @_Z3barUa9enable_ifIXLi1EEEi
40+
// CHECK: store void (i32)* @_Z3barUa9enable_ifILi1EEi
4141
p = &bar;
4242

43-
// CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*)
43+
// CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifILi1EEi to i8*)
4444
void *vp1 = (void*)&bar;
45-
// CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*)
45+
// CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifILi1EEi to i8*)
4646
void *vp2 = (void*)bar;
47-
// CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*)
47+
// CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifILi1EEi to i8*)
4848
vp1 = (void*)&bar;
49-
// CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifIXLi1EEEi to i8*)
49+
// CHECK: store i8* bitcast (void (i32)* @_Z3barUa9enable_ifILi1EEi to i8*)
5050
vp1 = (void*)bar;
5151
}
5252

5353
void baz(int m) __attribute__((overloadable, enable_if(1, "")));
5454
void baz(int m) __attribute__((overloadable));
5555
// CHECK-LABEL: define{{.*}} void @test3
5656
void test3() {
57-
// CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi
57+
// CHECK: store void (i32)* @_Z3bazUa9enable_ifILi1EEi
5858
void (*p)(int) = baz;
59-
// CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi
59+
// CHECK: store void (i32)* @_Z3bazUa9enable_ifILi1EEi
6060
void (*p2)(int) = &baz;
61-
// CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi
61+
// CHECK: store void (i32)* @_Z3bazUa9enable_ifILi1EEi
6262
p = baz;
63-
// CHECK: store void (i32)* @_Z3bazUa9enable_ifIXLi1EEEi
63+
// CHECK: store void (i32)* @_Z3bazUa9enable_ifILi1EEi
6464
p = &baz;
6565
}
6666

@@ -71,13 +71,13 @@ void qux(int m) __attribute__((overloadable, enable_if(1, ""),
7171
void qux(int m) __attribute__((overloadable, enable_if(1, "")));
7272
// CHECK-LABEL: define{{.*}} void @test4
7373
void test4() {
74-
// CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXLi1EEEi
74+
// CHECK: store void (i32)* @_Z3quxUa9enable_ifILi1ELi1EEi
7575
void (*p)(int) = qux;
76-
// CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXLi1EEEi
76+
// CHECK: store void (i32)* @_Z3quxUa9enable_ifILi1ELi1EEi
7777
void (*p2)(int) = &qux;
78-
// CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXLi1EEEi
78+
// CHECK: store void (i32)* @_Z3quxUa9enable_ifILi1ELi1EEi
7979
p = qux;
80-
// CHECK: store void (i32)* @_Z3quxUa9enable_ifIXLi1EEXLi1EEEi
80+
// CHECK: store void (i32)* @_Z3quxUa9enable_ifILi1ELi1EEi
8181
p = &qux;
8282
}
8383

@@ -90,6 +90,6 @@ void test5() {
9090
int foo(char *i __attribute__((pass_object_size(0))))
9191
__attribute__((enable_if(1, ""), overloadable));
9292

93-
// CHECK: call i32 @_Z3fooUa9enable_ifIXLi1EEEPcU17pass_object_size0
93+
// CHECK: call i32 @_Z3fooUa9enable_ifILi1EEPcU17pass_object_size0
9494
foo((void*)0);
9595
}

clang/test/CodeGenCXX/clang-abi-compat.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,9 @@ template void test7<A>(A::Int<1>);
130130
template<int N> using matrix1xN = int __attribute__((matrix_type(1, N)));
131131
template<int N> void test8(matrix1xN<N> a) {}
132132
template void test8<2>(matrix1xN<2> a);
133+
134+
// PRE12: @_ZN12expr_primary5test9EUa9enable_ifIXLi1EEEv
135+
// V12: @_ZN12expr_primary5test9EUa9enable_ifILi1EEv
136+
void test9(void) __attribute__((enable_if(1, ""))) {}
137+
133138
}

clang/test/CodeGenCXX/enable_if.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ int test5(int);
55
template <typename T>
66
T test5(T) __attribute__((enable_if(1, "better than non-template")));
77

8-
// CHECK: @_Z5test5IiEUa9enable_ifIXLi1EEET_S0_
8+
// CHECK: @_Z5test5IiEUa9enable_ifILi1EET_S0_
99
int (*Ptr)(int) = &test5;
1010

1111
// Test itanium mangling for attribute enable_if

0 commit comments

Comments
 (0)