Skip to content

Commit

Permalink
Mangle __unaligned in Itanium ABI
Browse files Browse the repository at this point in the history
__unaligned is not currently mangled in any way in the Itanium ABI. This causes
failures when using -fms-extensions and C++ in targets using Itanium ABI.

As suggested by @rsmith the simplest thing to do here is actually mangle the
qualifier as a vendor extension.

This patch also removes the change done in D31976 and updates its test to the
new reality.

This fixes
  https://bugs.llvm.org/show_bug.cgi?id=33080
  https://bugs.llvm.org/show_bug.cgi?id=33178

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

llvm-svn: 304523
  • Loading branch information
Roger Ferrer Ibanez committed Jun 2, 2017
1 parent 4d8748a commit fd9384a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 6 deletions.
22 changes: 16 additions & 6 deletions clang/lib/AST/ItaniumMangle.cpp
Expand Up @@ -1459,8 +1459,6 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
// We do not consider restrict a distinguishing attribute for overloading
// purposes so we must not mangle it.
MethodQuals.removeRestrict();
// __unaligned is not currently mangled in any way, so remove it.
MethodQuals.removeUnaligned();
mangleQualifiers(MethodQuals);
mangleRefQualifier(Method->getRefQualifier());
}
Expand Down Expand Up @@ -2140,7 +2138,8 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
}

void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
// Vendor qualifiers come first.
// Vendor qualifiers come first and if they are order-insensitive they must
// be emitted in reversed alphabetical order, see Itanium ABI 5.1.5.

// Address space qualifiers start with an ordinary letter.
if (Quals.hasAddressSpace()) {
Expand Down Expand Up @@ -2176,17 +2175,28 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
}

// The ARC ownership qualifiers start with underscores.
switch (Quals.getObjCLifetime()) {
// Objective-C ARC Extension:
//
// <type> ::= U "__strong"
// <type> ::= U "__weak"
// <type> ::= U "__autoreleasing"
//
// Note: we emit __weak first to preserve the order as
// required by the Itanium ABI.
if (Quals.getObjCLifetime() == Qualifiers::OCL_Weak)
mangleVendorQualifier("__weak");

// __unaligned (from -fms-extensions)
if (Quals.hasUnaligned())
mangleVendorQualifier("__unaligned");

// Remaining ARC ownership qualifiers.
switch (Quals.getObjCLifetime()) {
case Qualifiers::OCL_None:
break;

case Qualifiers::OCL_Weak:
mangleVendorQualifier("__weak");
// Do nothing as we already handled this case above.
break;

case Qualifiers::OCL_Strong:
Expand Down Expand Up @@ -4327,7 +4337,7 @@ bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) {
/// substitutions.
static bool hasMangledSubstitutionQualifiers(QualType T) {
Qualifiers Qs = T.getQualifiers();
return Qs.getCVRQualifiers() || Qs.hasAddressSpace();
return Qs.getCVRQualifiers() || Qs.hasAddressSpace() || Qs.hasUnaligned();
}

bool CXXNameMangler::mangleSubstitution(QualType T) {
Expand Down
33 changes: 33 additions & 0 deletions clang/test/CodeGenCXX/pr33080.cpp
@@ -0,0 +1,33 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -fms-extensions -emit-llvm -o- %s | FileCheck %s

void fa(__unaligned struct A *) {}
// CHECK: define void @_Z2faPU11__unaligned1A(

void ga(struct A *, struct A *) {}
// CHECK: define void @_Z2gaP1AS0_(

void gb(__unaligned struct A *, struct A *) {}
// CHECK: define void @_Z2gbPU11__unaligned1APS_(

void gc(struct A *, __unaligned struct A *) {}
// CHECK: define void @_Z2gcP1APU11__unalignedS_(

void gd(__unaligned struct A *, __unaligned struct A *) {}
// CHECK: define void @_Z2gdPU11__unaligned1AS1_(

void hb(__unaligned struct A *, __unaligned const struct A *) {}
// CHECK: define void @_Z2hbPU11__unaligned1APU11__unalignedKS_(

void ja(__unaligned struct A *, __unaligned struct A *__unaligned *, __unaligned struct A *__unaligned *__unaligned *) {}
// CHECK: define void @_Z2jaPU11__unaligned1APU11__unalignedS1_PU11__unalignedS3_(

void jb(__unaligned struct A *, __unaligned struct A **, __unaligned struct A *__unaligned *__unaligned *) {}
// CHECK: @_Z2jbPU11__unaligned1APS1_PU11__unalignedPU11__unalignedS1_(

template <typename T, typename Q>
void ta(T &, Q *) {}

void ia(__unaligned struct A &a) {
ta(a, &a);
}
// CHECK: @_Z2taIU11__unaligned1AS1_EvRT_PT0_(
20 changes: 20 additions & 0 deletions clang/test/CodeGenCXX/unaligned-member-qualifier.cpp
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -fms-extensions -emit-llvm %s -o- | FileCheck %s

struct A {
void foo() __unaligned;
void foo() const __unaligned;
void foo() volatile __unaligned;
void foo() const volatile __unaligned;
};

void A::foo() __unaligned {}
// CHECK: define void @_ZNU11__unaligned1A3fooEv(

void A::foo() const __unaligned {}
// CHECK: define void @_ZNU11__unalignedK1A3fooEv(

void A::foo() volatile __unaligned {}
// CHECK: define void @_ZNU11__unalignedV1A3fooEv(

void A::foo() const volatile __unaligned {}
// CHECK: define void @_ZNU11__unalignedVK1A3fooEv(
10 changes: 10 additions & 0 deletions clang/test/CodeGenObjCXX/arc-mangle.mm
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -triple %itanium_abi_triple -emit-llvm -fblocks -o - %s | FileCheck %s
// RUN: %clang_cc1 -DTEST_UNALIGNED -fms-extensions -fobjc-arc -fobjc-runtime-has-weak -triple %itanium_abi_triple -emit-llvm -fblocks -o - %s | FileCheck %s --check-prefix=UNALIGNED

// CHECK-LABEL: define {{.*}}void @_Z1fPU8__strongP11objc_object(i8**)
void f(__strong id *) {}
Expand Down Expand Up @@ -32,3 +33,12 @@ void f(void (^)(__attribute__((ns_consumed)) id)) {}
// CHECK-LABEL: define weak_odr {{.*}}void @_Z1gIKvEvP10unsigned_cIXplszv1U8__bridgecvPT_v1U8__bridgecvP11objc_objectcvS3_Li0ELi1EEE
template<typename T>void g(unsigned_c<sizeof((__bridge T*)(__bridge id)(T*)0) + 1>*) {}
template void g<const void>(unsigned_c<sizeof(id) + 1> *);

#if TEST_UNALIGNED
// UNALIGNED-LABEL: define {{.*}}void @_Z1gPU6__weakU11__unalignedP11objc_object(i8**)
void g(__weak __unaligned id *) {}
// UNALIGNED-LABEL: define {{.*}}void @_Z1gPU11__unalignedU8__strongP11objc_object(i8**)
void g(__strong __unaligned id *) {}
// UNALIGNED-LABEL: define {{.*}}void @_Z1gPU11__unalignedU15__autoreleasingP11objc_object(i8**)
void g(__autoreleasing __unaligned id *) {}
#endif // TEST_UNALIGNED

0 comments on commit fd9384a

Please sign in to comment.