r241251 - [MS ABI] nullptr data member ptrs are mangled differently for classes vs fns

David Majnemer david.majnemer at gmail.com
Thu Jul 2 02:43:14 PDT 2015


Author: majnemer
Date: Thu Jul  2 04:43:11 2015
New Revision: 241251

URL: http://llvm.org/viewvc/llvm-project?rev=241251&view=rev
Log:
[MS ABI] nullptr data member ptrs are mangled differently for classes vs fns

It turns out that nullptr pointers to data members act differently in
function templates vs class templates.  Class templates use a variable
width representation proportional to the number of fields needed to
materialize it.  Function templates always use a single '0' template
parameter.  However, using '0' all the time is problematic if the class
uses single or multiple inheritance.  In those cases, use -1.

Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=241251&r1=241250&r2=241251&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Thu Jul  2 04:43:11 2015
@@ -1215,11 +1215,23 @@ void MicrosoftCXXNameMangler::mangleTemp
         return;
       }
       if (MPT->isMemberDataPointer()) {
-        mangleMemberDataPointer(RD, nullptr);
-        return;
+        if (isa<ClassTemplateDecl>(TD)) {
+          mangleMemberDataPointer(RD, nullptr);
+          return;
+        }
+        // nullptr data pointers are always represented with a single field
+        // which is initialized with either 0 or -1.  Why -1?  Well, we need to
+        // distinguish the case where the data member is at offset zero in the
+        // record.
+        // However, we are free to use 0 *if* we would use multiple fields for
+        // non-nullptr member pointers.
+        if (!RD->nullFieldOffsetIsZero()) {
+          mangleIntegerLiteral(llvm::APSInt::get(-1), /*IsBoolean=*/false);
+          return;
+        }
       }
     }
-    Out << "$0A@";
+    mangleIntegerLiteral(llvm::APSInt::getUnsigned(0), /*IsBoolean=*/false);
     break;
   }
   case TemplateArgument::Expression:

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp?rev=241251&r1=241250&r2=241251&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp Thu Jul  2 04:43:11 2015
@@ -3,22 +3,37 @@
 template <typename T, int (T::*)() = nullptr>
 struct J {};
 
+template <typename T, int T::* = nullptr>
+struct K {};
+
 struct __single_inheritance M;
 J<M> m;
 // CHECK-DAG: @"\01?m@@3U?$J at UM@@$0A@@@A"
 
+K<M> m2;
+// CHECK-DAG: @"\01?m2@@3U?$K at UM@@$0?0@@A"
+
 struct __multiple_inheritance N;
 J<N> n;
 // CHECK-DAG: @"\01?n@@3U?$J at UN@@$HA@@@A"
 
+K<N> n2;
+// CHECK-DAG: @"\01?n2@@3U?$K at UN@@$0?0@@A"
+
 struct __virtual_inheritance O;
 J<O> o;
 // CHECK-DAG: @"\01?o@@3U?$J at UO@@$IA at A@@@A"
 
+K<O> o2;
+// CHECK-DAG: @"\01?o2@@3U?$K at UO@@$FA@?0@@A"
+
 struct P;
 J<P> p;
 // CHECK-DAG: @"\01?p@@3U?$J at UP@@$JA at A@?0@@A"
 
+K<P> p2;
+// CHECK-DAG: @"\01?p2@@3U?$K at UP@@$GA at A@?0@@A"
+
 #pragma pointers_to_members(full_generality, virtual_inheritance)
 
 struct S {

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp?rev=241251&r1=241250&r2=241251&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp Thu Jul  2 04:43:11 2015
@@ -69,8 +69,8 @@ void ReadFields() {
 // them right in class templates.
 // CHECK: call {{.*}} @"\01??$ReadField at US@@$0A@@@YAHAAUS@@@Z"
 // CHECK: call {{.*}} @"\01??$ReadField at UM@@$0A@@@YAHAAUM@@@Z"
-// CHECK: call {{.*}} @"\01??$ReadField at UV@@$FA@?0@@YAHAAUV@@@Z"
-// CHECK: call {{.*}} @"\01??$ReadField at UU@@$GA at A@?0@@YAHAAUU@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField at UV@@$0A@@@YAHAAUV@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField at UU@@$0A@@@YAHAAUU@@@Z"
 
 // Non-polymorphic null data memptr vs first field memptr.  MSVC mangles these
 // the same.





More information about the cfe-commits mailing list