]> granicus.if.org Git - clang/commitdiff
Avoid assert when a non-static member function is qualified with __unaligned
authorRoger Ferrer Ibanez <roger.ferreribanez@arm.com>
Wed, 19 Apr 2017 12:23:28 +0000 (12:23 +0000)
committerRoger Ferrer Ibanez <roger.ferreribanez@arm.com>
Wed, 19 Apr 2017 12:23:28 +0000 (12:23 +0000)
Under -fms-extensions __unaligned is a type-qualifier that can be applied to a
non-static member function declaration.

This causes an assertion when mangling the name under Itanium, where that
qualifier is not mangled.

This patch justs makes the minimal change to avoid the crash and avoid mangling
__unaligned, as it currently happens with non-member functions.

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@300686 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ItaniumMangle.cpp
test/CodeGenCXX/unaligned-duplicated-mangle-name.cpp [new file with mode: 0644]

index 29fcdd7be924559cf3b3aebb4e48e19b5c3dcebc..7db0b4d8e4ff74aa67ea7ca7b3760ec260127ec8 100644 (file)
@@ -1455,10 +1455,12 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
   Out << 'N';
   if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND)) {
     Qualifiers MethodQuals =
-        Qualifiers::fromCVRMask(Method->getTypeQualifiers());
+        Qualifiers::fromCVRUMask(Method->getTypeQualifiers());
     // 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());
   }
diff --git a/test/CodeGenCXX/unaligned-duplicated-mangle-name.cpp b/test/CodeGenCXX/unaligned-duplicated-mangle-name.cpp
new file mode 100644 (file)
index 0000000..a23e6a4
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fms-extensions -emit-llvm-only %s -verify
+
+struct A
+{
+    int x;
+    void foo() __unaligned;
+    void foo();
+};
+
+void A::foo() __unaligned
+{
+    this->x++;
+}
+
+void A::foo() // expected-error {{definition with same mangled name as another definition}}
+              // expected-note@-6 {{previous definition is here}}
+{
+    this->x++;
+}
+