r232766 - MS ABI: Implement the MSVC 2015 scheme for scope disambiguation

David Majnemer david.majnemer at gmail.com
Thu Mar 19 14:54:30 PDT 2015


Author: majnemer
Date: Thu Mar 19 16:54:30 2015
New Revision: 232766

URL: http://llvm.org/viewvc/llvm-project?rev=232766&view=rev
Log:
MS ABI: Implement the MSVC 2015 scheme for scope disambiguation

consider C++ that looks like:
  inline int &f(bool b) {
    if (b) {
      static int i;
      return i;
    }
    static int i;
    return i;
  }

Both 'i' variables must have distinct (and stable) names for linkage
purposes.  The MSVC 2013 ABI would number the variables using a count of
the number of scopes that have been created.  However, the final 'i'
returns to a scope that has already been created leading to a mangling
collision.

MSVC 2015 fixes this by giving the second 'i' the name it would have if
it were declared before the 'if'.  However, this results in ABI breakage
because the mangled name, in cases where there was no ambiguity, would
now be different.

We implement the new behavior and only enable it if we are targeting the
MSVC 2015 ABI, otherwise the old behavior will be used.

This fixes PR18131.

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Scope.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/lib/Sema/Scope.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-abi-examples.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-cxx14.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=232766&r1=232765&r2=232766&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Mar 19 16:54:30 2015
@@ -245,8 +245,8 @@ public:
 
   const Token &getCurToken() const { return Tok; }
   Scope *getCurScope() const { return Actions.getCurScope(); }
-  void incrementMSLocalManglingNumber() const {
-    return Actions.incrementMSLocalManglingNumber();
+  void incrementMSManglingNumber() const {
+    return Actions.incrementMSManglingNumber();
   }
 
   Decl  *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
@@ -759,7 +759,7 @@ public:
         Self->EnterScope(ScopeFlags);
       else {
         if (BeforeCompoundStmt)
-          Self->incrementMSLocalManglingNumber();
+          Self->incrementMSManglingNumber();
 
         this->Self = nullptr;
       }

Modified: cfe/trunk/include/clang/Sema/Scope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Scope.h?rev=232766&r1=232765&r2=232766&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Scope.h (original)
+++ cfe/trunk/include/clang/Sema/Scope.h Thu Mar 19 16:54:30 2015
@@ -139,7 +139,9 @@ private:
 
   /// \brief Declarations with static linkage are mangled with the number of
   /// scopes seen as a component.
-  unsigned short MSLocalManglingNumber;
+  unsigned short MSLastManglingNumber;
+
+  unsigned short MSCurManglingNumber;
 
   /// PrototypeDepth - This is the number of function prototype scopes
   /// enclosing this scope, including this scope.
@@ -152,7 +154,7 @@ private:
   /// FnParent - If this scope has a parent scope that is a function body, this
   /// pointer is non-null and points to it.  This is used for label processing.
   Scope *FnParent;
-  Scope *MSLocalManglingParent;
+  Scope *MSLastManglingParent;
 
   /// BreakParent/ContinueParent - This is a direct link to the innermost
   /// BreakScope/ContinueScope which contains the contents of this scope
@@ -218,10 +220,10 @@ public:
   const Scope *getFnParent() const { return FnParent; }
   Scope *getFnParent() { return FnParent; }
 
-  const Scope *getMSLocalManglingParent() const {
-    return MSLocalManglingParent;
+  const Scope *getMSLastManglingParent() const {
+    return MSLastManglingParent;
   }
-  Scope *getMSLocalManglingParent() { return MSLocalManglingParent; }
+  Scope *getMSLastManglingParent() { return MSLastManglingParent; }
 
   /// getContinueParent - Return the closest scope that a continue statement
   /// would be affected by.
@@ -275,20 +277,28 @@ public:
     DeclsInScope.erase(D);
   }
 
-  void incrementMSLocalManglingNumber() {
-    if (Scope *MSLMP = getMSLocalManglingParent())
-      MSLMP->MSLocalManglingNumber += 1;
-  }
-
-  void decrementMSLocalManglingNumber() {
-    if (Scope *MSLMP = getMSLocalManglingParent())
-      MSLMP->MSLocalManglingNumber -= 1;
+  void incrementMSManglingNumber() {
+    if (Scope *MSLMP = getMSLastManglingParent()) {
+      MSLMP->MSLastManglingNumber += 1;
+      MSCurManglingNumber += 1;
+    }
+  }
+
+  void decrementMSManglingNumber() {
+    if (Scope *MSLMP = getMSLastManglingParent()) {
+      MSLMP->MSLastManglingNumber -= 1;
+      MSCurManglingNumber -= 1;
+    }
+  }
+
+  unsigned getMSLastManglingNumber() const {
+    if (const Scope *MSLMP = getMSLastManglingParent())
+      return MSLMP->MSLastManglingNumber;
+    return 1;
   }
 
-  unsigned getMSLocalManglingNumber() const {
-    if (const Scope *MSLMP = getMSLocalManglingParent())
-      return MSLMP->MSLocalManglingNumber;
-    return 1;
+  unsigned getMSCurManglingNumber() const {
+    return MSCurManglingNumber;
   }
 
   /// isDeclScope - Return true if this is the scope that the specified decl is

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=232766&r1=232765&r2=232766&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Mar 19 16:54:30 2015
@@ -8610,8 +8610,8 @@ public:
   /// template substitution or instantiation.
   Scope *getCurScope() const { return CurScope; }
 
-  void incrementMSLocalManglingNumber() const {
-    return CurScope->incrementMSLocalManglingNumber();
+  void incrementMSManglingNumber() const {
+    return CurScope->incrementMSManglingNumber();
   }
 
   IdentifierInfo *getSuperIdentifier() const;

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=232766&r1=232765&r2=232766&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Mar 19 16:54:30 2015
@@ -1268,7 +1268,7 @@ StmtResult Parser::ParseSwitchStatement(
   // We have incremented the mangling number for the SwitchScope and the
   // InnerScope, which is one too many.
   if (C99orCXX)
-    getCurScope()->decrementMSLocalManglingNumber();
+    getCurScope()->decrementMSManglingNumber();
 
   // Read the body statement.
   StmtResult Body(ParseStatement(TrailingElseLoc));
@@ -1710,7 +1710,7 @@ StmtResult Parser::ParseForStatement(Sou
   // It will only be incremented if the body contains other things that would
   // normally increment the mangling number (like a compound statement).
   if (C99orCXXorObjC)
-    getCurScope()->decrementMSLocalManglingNumber();
+    getCurScope()->decrementMSManglingNumber();
 
   // Read the body statement.
   StmtResult Body(ParseStatement(TrailingElseLoc));

Modified: cfe/trunk/lib/Sema/Scope.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Scope.cpp?rev=232766&r1=232765&r2=232766&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Scope.cpp (original)
+++ cfe/trunk/lib/Sema/Scope.cpp Thu Mar 19 16:54:30 2015
@@ -38,7 +38,8 @@ void Scope::Init(Scope *parent, unsigned
     FnParent       = parent->FnParent;
     BlockParent    = parent->BlockParent;
     TemplateParamParent = parent->TemplateParamParent;
-    MSLocalManglingParent = parent->MSLocalManglingParent;
+    MSLastManglingParent = parent->MSLastManglingParent;
+    MSCurManglingNumber = getMSLastManglingNumber();
     if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
                   FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
         0)
@@ -47,9 +48,10 @@ void Scope::Init(Scope *parent, unsigned
     Depth = 0;
     PrototypeDepth = 0;
     PrototypeIndex = 0;
-    MSLocalManglingParent = FnParent = BlockParent = nullptr;
+    MSLastManglingParent = FnParent = BlockParent = nullptr;
     TemplateParamParent = nullptr;
-    MSLocalManglingNumber = 1;
+    MSLastManglingNumber = 1;
+    MSCurManglingNumber = 1;
   }
 
   // If this scope is a function or contains breaks/continues, remember it.
@@ -57,8 +59,9 @@ void Scope::Init(Scope *parent, unsigned
   // The MS mangler uses the number of scopes that can hold declarations as
   // part of an external name.
   if (Flags & (ClassScope | FnScope)) {
-    MSLocalManglingNumber = getMSLocalManglingNumber();
-    MSLocalManglingParent = this;
+    MSLastManglingNumber = getMSLastManglingNumber();
+    MSLastManglingParent = this;
+    MSCurManglingNumber = 1;
   }
   if (flags & BreakScope)         BreakParent = this;
   if (flags & ContinueScope)      ContinueParent = this;
@@ -78,7 +81,7 @@ void Scope::Init(Scope *parent, unsigned
     else if ((flags & EnumScope))
       ; // Don't increment for enum scopes.
     else
-      incrementMSLocalManglingNumber();
+      incrementMSManglingNumber();
   }
 
   DeclsInScope.clear();
@@ -209,12 +212,13 @@ void Scope::dumpImpl(raw_ostream &OS) co
     OS << "Parent: (clang::Scope*)" << Parent << '\n';
 
   OS << "Depth: " << Depth << '\n';
-  OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n';
+  OS << "MSLastManglingNumber: " << getMSLastManglingNumber() << '\n';
+  OS << "MSCurManglingNumber: " << getMSCurManglingNumber() << '\n';
   if (const DeclContext *DC = getEntity())
     OS << "Entity : (clang::DeclContext*)" << DC << '\n';
 
   if (NRVO.getInt())
-    OS << "NRVO not allowed";
+    OS << "NRVO not allowed\n";
   else if (NRVO.getPointer())
     OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';
 }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=232766&r1=232765&r2=232766&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Mar 19 16:54:30 2015
@@ -3416,6 +3416,17 @@ Decl *Sema::ParsedFreeStandingDeclSpec(S
   return ParsedFreeStandingDeclSpec(S, AS, DS, MultiTemplateParamsArg());
 }
 
+// The MS ABI changed between VS2013 and VS2015 with regard to numbers used to
+// disambiguate entities defined in different scopes.
+// While the VS2015 ABI fixes potential miscompiles, it is also breaks
+// compatibility.
+// We will pick our mangling number depending on which version of MSVC is being
+// targeted.
+static unsigned getMSManglingNumber(const LangOptions &LO, Scope *S) {
+  return LO.isCompatibleWithMSVC(19) ? S->getMSCurManglingNumber()
+                                     : S->getMSLastManglingNumber();
+}
+
 void Sema::handleTagNumbering(const TagDecl *Tag, Scope *TagScope) {
   if (!Context.getLangOpts().CPlusPlus)
     return;
@@ -3428,7 +3439,8 @@ void Sema::handleTagNumbering(const TagD
     MangleNumberingContext &MCtx =
         Context.getManglingNumberContext(Tag->getParent());
     Context.setManglingNumber(
-        Tag, MCtx.getManglingNumber(Tag, TagScope->getMSLocalManglingNumber()));
+        Tag, MCtx.getManglingNumber(
+                 Tag, getMSManglingNumber(getLangOpts(), TagScope)));
     return;
   }
 
@@ -3437,8 +3449,8 @@ void Sema::handleTagNumbering(const TagD
   if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext(
           Tag->getDeclContext(), ManglingContextDecl)) {
     Context.setManglingNumber(
-        Tag,
-        MCtx->getManglingNumber(Tag, TagScope->getMSLocalManglingNumber()));
+        Tag, MCtx->getManglingNumber(
+                 Tag, getMSManglingNumber(getLangOpts(), TagScope)));
   }
 }
 
@@ -4135,10 +4147,11 @@ Decl *Sema::BuildAnonymousStructOrUnion(
   if (VarDecl *NewVD = dyn_cast<VarDecl>(Anon)) {
     if (getLangOpts().CPlusPlus && NewVD->isStaticLocal()) {
       Decl *ManglingContextDecl;
-      if (MangleNumberingContext *MCtx =
-              getCurrentMangleNumberContext(NewVD->getDeclContext(),
-                                            ManglingContextDecl)) {
-        Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber()));
+      if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext(
+              NewVD->getDeclContext(), ManglingContextDecl)) {
+        Context.setManglingNumber(
+            NewVD, MCtx->getManglingNumber(
+                       NewVD, getMSManglingNumber(getLangOpts(), S)));
         Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD));
       }
     }
@@ -5925,11 +5938,11 @@ Sema::ActOnVariableDeclarator(Scope *S,
 
   if (getLangOpts().CPlusPlus && NewVD->isStaticLocal()) {
     Decl *ManglingContextDecl;
-    if (MangleNumberingContext *MCtx =
-            getCurrentMangleNumberContext(NewVD->getDeclContext(),
-                                          ManglingContextDecl)) {
+    if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext(
+            NewVD->getDeclContext(), ManglingContextDecl)) {
       Context.setManglingNumber(
-          NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber()));
+          NewVD, MCtx->getManglingNumber(
+                     NewVD, getMSManglingNumber(getLangOpts(), S)));
       Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD));
     }
   }

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-abi-examples.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-abi-examples.cpp?rev=232766&r1=232765&r2=232766&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-abi-examples.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-abi-examples.cpp Thu Mar 19 16:54:30 2015
@@ -1,8 +1,10 @@
-// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2015
+// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=18.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2013
 
 // CHECK: @"\01??_7B@?1??foo at A@@QAEXH at Z@6B@" =
 // CHECK: @"\01??_7D at C@?1??foo@@YAXXZ at 6B@" =
-// CHECK: define {{.*}} @"\01?baz at E@?3??bar at C@?1??foo@@YAXXZ at QAEXXZ@QAEXXZ"(
+// MSVC2013: define {{.*}} @"\01?baz at E@?3??bar at C@?1??foo@@YAXXZ at QAEXXZ@QAEXXZ"(
+// MSVC2015: define {{.*}} @"\01?baz at E@?1??bar at C@?1??foo@@YAXXZ at QAEXXZ@QAEXXZ"(
 
 // Microsoft Visual C++ ABI examples.
 struct A {

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp?rev=232766&r1=232765&r2=232766&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp Thu Mar 19 16:54:30 2015
@@ -172,7 +172,8 @@ inline int define_lambda() {
 // CHECK-DAG: @"\01??R<lambda_1>@?define_lambda@@YAHXZ at QBEHXZ"
 // Finally, we have the local which is inside of "<lambda_1>" which is inside of
 // "define_lambda". Hooray.
-// CHECK-DAG: @"\01?local@?2???R<lambda_1>@?define_lambda@@YAHXZ at QBEHXZ@4HA"
+// MSVC2013-DAG: @"\01?local@?2???R<lambda_1>@?define_lambda@@YAHXZ at QBEHXZ@4HA"
+// MSVC2015-DAG: @"\01?local@?1???R<lambda_1>@?define_lambda@@YAHXZ at QBEHXZ@4HA"
   return lambda();
 }
 

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-cxx14.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-cxx14.cpp?rev=232766&r1=232765&r2=232766&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-cxx14.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-cxx14.cpp Thu Mar 19 16:54:30 2015
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2015
+// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=18.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2013
 
 template <typename> int x = 0;
 
@@ -34,7 +35,10 @@ auto TemplateFuncionWithLocalLambda(T) {
   return LocalLambdaWithLocalType();
 }
 
-// CHECK: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z@QBA?A?3 at XZ@A"
+// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z@QBA?A?3 at XZ@A"
+// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z@QBA?A?3 at XZ@A"
+// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z@QBA?A?3 at XZ@A"
+// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z@QBA?A?3 at XZ@A"
 // CHECK: "\01??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z"
 // CHECK: "\01??R<lambda_1>@??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z@QBA?A?1 at XZ"
 auto ValueFromTemplateFuncionWithLocalLambda = TemplateFuncionWithLocalLambda(0);





More information about the cfe-commits mailing list