<div dir="ltr">Hi,<div><br></div><div>I don't know if you've noticed, but this commit broke a lot of builds - e.g. <a href="http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-a15/builds/11865">http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-a15/builds/11865</a>.</div><div><br></div><div>Regards,</div><div>Diana</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 28 April 2016 at 13:13, Denis Zobnin via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dzobnin<br>
Date: Thu Apr 28 05:13:18 2016<br>
New Revision: 267866<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=267866&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=267866&view=rev</a><br>
Log:<br>
[MS] Improved implementation of MS stack pragmas (vtordisp, *_seg)<br>
<br>
Rework implementation of several MS pragmas that use internal stack:<br>
vtordisp, {bss|code|const|data}_seg.<br>
This patch:<br>
  1. Makes #pragma vtordisp use PragmaStack class as *_seg pragmas do;<br>
  2. Fixes "#pragma vtordisp()" behavior: it shouldn't affect stack;<br>
  3. Saves/restores the stacks on enter/exit a C++ method body.<br>
<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/Parse/ParsePragma.cpp<br>
    cfe/trunk/lib/Parse/ParseStmt.cpp<br>
    cfe/trunk/lib/Sema/Sema.cpp<br>
    cfe/trunk/lib/Sema/SemaAttr.cpp<br>
    cfe/trunk/test/CodeGenCXX/sections.cpp<br>
    cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=267866&r1=267865&r2=267866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=267866&r1=267865&r2=267866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Apr 28 05:13:18 2016<br>
@@ -327,40 +327,21 @@ public:<br>
   LangOptions::PragmaMSPointersToMembersKind<br>
       MSPointerToMemberRepresentationMethod;<br>
<br>
-  enum PragmaVtorDispKind {<br>
-    PVDK_Push,          ///< #pragma vtordisp(push, mode)<br>
-    PVDK_Set,           ///< #pragma vtordisp(mode)<br>
-    PVDK_Pop,           ///< #pragma vtordisp(pop)<br>
-    PVDK_Reset          ///< #pragma vtordisp()<br>
-  };<br>
-<br>
-  enum PragmaMsStackAction {<br>
-    PSK_Reset,    // #pragma ()<br>
-    PSK_Set,      // #pragma ("name")<br>
-    PSK_Push,     // #pragma (push[, id])<br>
-    PSK_Push_Set, // #pragma (push[, id], "name")<br>
-    PSK_Pop,      // #pragma (pop[, id])<br>
-    PSK_Pop_Set,  // #pragma (pop[, id], "name")<br>
-  };<br>
-<br>
-  /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft<br>
-  /// C++ ABI.  Possible values are 0, 1, and 2, which mean:<br>
-  ///<br>
-  /// 0: Suppress all vtordisps<br>
-  /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial<br>
-  ///    structors<br>
-  /// 2: Always insert vtordisps to support RTTI on partially constructed<br>
-  ///    objects<br>
-  ///<br>
-  /// The stack always has at least one element in it.<br>
-  SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack;<br>
-<br>
   /// Stack of active SEH __finally scopes.  Can be empty.<br>
   SmallVector<Scope*, 2> CurrentSEHFinally;<br>
<br>
   /// \brief Source location for newly created implicit MSInheritanceAttrs<br>
   SourceLocation ImplicitMSInheritanceAttrLoc;<br>
<br>
+  enum PragmaMsStackAction {<br>
+    PSK_Reset     = 0x0,                // #pragma ()<br>
+    PSK_Set       = 0x1,                // #pragma (value)<br>
+    PSK_Push      = 0x2,                // #pragma (push[, id])<br>
+    PSK_Pop       = 0x4,                // #pragma (pop[, id])<br>
+    PSK_Push_Set  = PSK_Push | PSK_Set, // #pragma (push[, id], value)<br>
+    PSK_Pop_Set   = PSK_Pop | PSK_Set,  // #pragma (pop[, id], value)<br>
+  };<br>
+<br>
   template<typename ValueType><br>
   struct PragmaStack {<br>
     struct Slot {<br>
@@ -377,18 +358,84 @@ public:<br>
              PragmaMsStackAction Action,<br>
              llvm::StringRef StackSlotLabel,<br>
              ValueType Value);<br>
-    explicit PragmaStack(const ValueType &Value)<br>
-      : CurrentValue(Value) {}<br>
+<br>
+    // MSVC seems to add artificial slots to #pragma stacks on entering a C++<br>
+    // method body to restore the stacks on exit, so it works like this:<br>
+    //<br>
+    //   struct S {<br>
+    //     #pragma <name>(push, InternalPragmaSlot, <current_pragma_value>)<br>
+    //     void Method {}<br>
+    //     #pragma <name>(pop, InternalPragmaSlot)<br>
+    //   };<br>
+    //<br>
+    // It works even with #pragma vtordisp, although MSVC doesn't support<br>
+    //   #pragma vtordisp(push [, id], n)<br>
+    // syntax.<br>
+    //<br>
+    // Push / pop a named sentinel slot.<br>
+    void SentinelAction(PragmaMsStackAction Action, StringRef Label) {<br>
+      assert((Action == PSK_Push || Action == PSK_Pop) &&<br>
+             "Can only push / pop #pragma stack sentinels!");<br>
+      Act(CurrentPragmaLocation, Action, Label, CurrentValue);<br>
+    }<br>
+<br>
+    // Constructors.<br>
+    explicit PragmaStack(const ValueType &Default)<br>
+        : DefaultValue(Default), CurrentValue(Default) {}<br>
+<br>
     SmallVector<Slot, 2> Stack;<br>
+    ValueType DefaultValue; // Value used for PSK_Reset action.<br>
     ValueType CurrentValue;<br>
     SourceLocation CurrentPragmaLocation;<br>
   };<br>
   // FIXME: We should serialize / deserialize these if they occur in a PCH (but<br>
   // we shouldn't do so if they're in a module).<br>
+<br>
+  /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft<br>
+  /// C++ ABI.  Possible values are 0, 1, and 2, which mean:<br>
+  ///<br>
+  /// 0: Suppress all vtordisps<br>
+  /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial<br>
+  ///    structors<br>
+  /// 2: Always insert vtordisps to support RTTI on partially constructed<br>
+  ///    objects<br>
+  PragmaStack<MSVtorDispAttr::Mode> VtorDispStack;<br>
   PragmaStack<StringLiteral *> DataSegStack;<br>
   PragmaStack<StringLiteral *> BSSSegStack;<br>
   PragmaStack<StringLiteral *> ConstSegStack;<br>
   PragmaStack<StringLiteral *> CodeSegStack;<br>
+  // TODO: Change implementation of #pragma pack to use PragmaStack<> approach.<br>
+<br>
+  // RAII object to psuh / pop sentinel slots for all MS #pragma stacks.<br>
+  // Actions should be performed only if we enter / exit a C++ method body.<br>
+  class PragmaStackSentinelRAII {<br>
+  public:<br>
+    PragmaStackSentinelRAII(Sema &S, StringRef SlotLabel, bool ShouldAct)<br>
+        : S(S), SlotLabel(SlotLabel), ShouldAct(ShouldAct) {<br>
+      if (ShouldAct) {<br>
+        S.VtorDispStack.SentinelAction(PSK_Push, SlotLabel);<br>
+        S.DataSegStack.SentinelAction(PSK_Push, SlotLabel);<br>
+        S.BSSSegStack.SentinelAction(PSK_Push, SlotLabel);<br>
+        S.ConstSegStack.SentinelAction(PSK_Push, SlotLabel);<br>
+        S.CodeSegStack.SentinelAction(PSK_Push, SlotLabel);<br>
+      }<br>
+    }<br>
+<br>
+    ~PragmaStackSentinelRAII() {<br>
+      if (ShouldAct) {<br>
+        S.VtorDispStack.SentinelAction(PSK_Pop, SlotLabel);<br>
+        S.DataSegStack.SentinelAction(PSK_Pop, SlotLabel);<br>
+        S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel);<br>
+        S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel);<br>
+        S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel);<br>
+      }<br>
+    }<br>
+<br>
+  private:<br>
+    Sema &S;<br>
+    StringRef SlotLabel;<br>
+    bool ShouldAct;<br>
+  };<br>
<br>
   /// A mapping that describes the nullability we've seen in each header file.<br>
   FileNullabilityMap NullabilityMap;<br>
@@ -1011,24 +1058,6 @@ public:<br>
     bool OldFPContractState : 1;<br>
   };<br>
<br>
-  /// Records and restores the vtordisp state on entry/exit of C++ method body.<br>
-  class VtorDispStackRAII {<br>
-  public:<br>
-    VtorDispStackRAII(Sema &S, bool ShouldSaveAndRestore)<br>
-      : S(S), ShouldSaveAndRestore(ShouldSaveAndRestore), OldVtorDispStack() {<br>
-      if (ShouldSaveAndRestore)<br>
-        OldVtorDispStack = S.VtorDispModeStack;<br>
-    }<br>
-    ~VtorDispStackRAII() {<br>
-      if (ShouldSaveAndRestore)<br>
-        S.VtorDispModeStack = OldVtorDispStack;<br>
-    }<br>
-  private:<br>
-    Sema &S;<br>
-    bool ShouldSaveAndRestore;<br>
-    SmallVector<MSVtorDispAttr::Mode, 2> OldVtorDispStack;<br>
-  };<br>
-<br>
   void addImplicitTypedef(StringRef Name, QualType T);<br>
<br>
 public:<br>
@@ -7666,7 +7695,8 @@ public:<br>
       SourceLocation PragmaLoc);<br>
<br>
   /// \brief Called on well formed \#pragma vtordisp().<br>
-  void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation PragmaLoc,<br>
+  void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action,<br>
+                             SourceLocation PragmaLoc,<br>
                              MSVtorDispAttr::Mode Value);<br>
<br>
   enum PragmaSectionKind {<br>
<br>
Modified: cfe/trunk/lib/Parse/ParsePragma.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=267866&r1=267865&r2=267866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=267866&r1=267865&r2=267866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Thu Apr 28 05:13:18 2016<br>
@@ -497,11 +497,11 @@ void Parser::HandlePragmaMSPointersToMem<br>
 void Parser::HandlePragmaMSVtorDisp() {<br>
   assert(Tok.is(tok::annot_pragma_ms_vtordisp));<br>
   uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());<br>
-  Sema::PragmaVtorDispKind Kind =<br>
-      static_cast<Sema::PragmaVtorDispKind>((Value >> 16) & 0xFFFF);<br>
+  Sema::PragmaMsStackAction Action =<br>
+      static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);<br>
   MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);<br>
   SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.<br>
-  Actions.ActOnPragmaMSVtorDisp(Kind, PragmaLoc, Mode);<br>
+  Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);<br>
 }<br>
<br>
 void Parser::HandlePragmaMSPragma() {<br>
@@ -1606,7 +1606,7 @@ void PragmaMSVtorDisp::HandlePragma(Prep<br>
   }<br>
   PP.Lex(Tok);<br>
<br>
-  Sema::PragmaVtorDispKind Kind = Sema::PVDK_Set;<br>
+  Sema::PragmaMsStackAction Action = Sema::PSK_Set;<br>
   const IdentifierInfo *II = Tok.getIdentifierInfo();<br>
   if (II) {<br>
     if (II->isStr("push")) {<br>
@@ -1617,24 +1617,24 @@ void PragmaMSVtorDisp::HandlePragma(Prep<br>
         return;<br>
       }<br>
       PP.Lex(Tok);<br>
-      Kind = Sema::PVDK_Push;<br>
+      Action = Sema::PSK_Push_Set;<br>
       // not push, could be on/off<br>
     } else if (II->isStr("pop")) {<br>
       // #pragma vtordisp(pop)<br>
       PP.Lex(Tok);<br>
-      Kind = Sema::PVDK_Pop;<br>
+      Action = Sema::PSK_Pop;<br>
     }<br>
     // not push or pop, could be on/off<br>
   } else {<br>
     if (Tok.is(tok::r_paren)) {<br>
       // #pragma vtordisp()<br>
-      Kind = Sema::PVDK_Reset;<br>
+      Action = Sema::PSK_Reset;<br>
     }<br>
   }<br>
<br>
<br>
   uint64_t Value = 0;<br>
-  if (Kind == Sema::PVDK_Push || Kind == Sema::PVDK_Set) {<br>
+  if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {<br>
     const IdentifierInfo *II = Tok.getIdentifierInfo();<br>
     if (II && II->isStr("off")) {<br>
       PP.Lex(Tok);<br>
@@ -1676,7 +1676,7 @@ void PragmaMSVtorDisp::HandlePragma(Prep<br>
   AnnotTok.setLocation(VtorDispLoc);<br>
   AnnotTok.setAnnotationEndLoc(EndLoc);<br>
   AnnotTok.setAnnotationValue(reinterpret_cast<void *>(<br>
-      static_cast<uintptr_t>((Kind << 16) | (Value & 0xFFFF))));<br>
+      static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));<br>
   PP.EnterToken(AnnotTok);<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=267866&r1=267865&r2=267866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=267866&r1=267865&r2=267866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Apr 28 05:13:18 2016<br>
@@ -1928,7 +1928,8 @@ Decl *Parser::ParseFunctionStatementBody<br>
   // Save and reset current vtordisp stack if we have entered a C++ method body.<br>
   bool IsCXXMethod =<br>
       getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl);<br>
-  Sema::VtorDispStackRAII SavedVtorDispStack(Actions, IsCXXMethod);<br>
+  Sema::PragmaStackSentinelRAII<br>
+    PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);<br>
<br>
   // Do not enter a scope for the brace, as the arguments are in the same scope<br>
   // (the function body) as the body itself.  Instead, just read the statement<br>
@@ -1972,7 +1973,8 @@ Decl *Parser::ParseFunctionTryBlock(Decl<br>
   // Save and reset current vtordisp stack if we have entered a C++ method body.<br>
   bool IsCXXMethod =<br>
       getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl);<br>
-  Sema::VtorDispStackRAII SavedVtorDispStack(Actions, IsCXXMethod);<br>
+  Sema::PragmaStackSentinelRAII<br>
+    PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod);<br>
<br>
   SourceLocation LBraceLoc = Tok.getLocation();<br>
   StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true));<br>
<br>
Modified: cfe/trunk/lib/Sema/Sema.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=267866&r1=267865&r2=267866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=267866&r1=267865&r2=267866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/Sema.cpp (original)<br>
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Apr 28 05:13:18 2016<br>
@@ -82,7 +82,7 @@ Sema::Sema(Preprocessor &pp, ASTContext<br>
     PackContext(nullptr), MSStructPragmaOn(false),<br>
     MSPointerToMemberRepresentationMethod(<br>
         LangOpts.getMSPointerToMemberRepresentationMethod()),<br>
-    VtorDispModeStack(1, MSVtorDispAttr::Mode(LangOpts.VtorDispMode)),<br>
+    VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)),<br>
     DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr),<br>
     CodeSegStack(nullptr), CurInitSeg(nullptr), VisContext(nullptr),<br>
     IsBuildingRecoveryCallExpr(false),<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaAttr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=267866&r1=267865&r2=267866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=267866&r1=267865&r2=267866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Thu Apr 28 05:13:18 2016<br>
@@ -136,9 +136,9 @@ void Sema::AddMsStructLayoutForRecord(Re<br>
   // FIXME: We should merge AddAlignmentAttributesForRecord with<br>
   // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes<br>
   // all active pragmas and applies them as attributes to class definitions.<br>
-  if (VtorDispModeStack.back() != getLangOpts().VtorDispMode)<br>
+  if (VtorDispStack.CurrentValue != getLangOpts().VtorDispMode)<br>
     RD->addAttr(<br>
-        MSVtorDispAttr::CreateImplicit(Context, VtorDispModeStack.back()));<br>
+        MSVtorDispAttr::CreateImplicit(Context, VtorDispStack.CurrentValue));<br>
 }<br>
<br>
 void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,<br>
@@ -292,29 +292,13 @@ void Sema::ActOnPragmaMSPointersToMember<br>
   ImplicitMSInheritanceAttrLoc = PragmaLoc;<br>
 }<br>
<br>
-void Sema::ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind,<br>
+void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action,<br>
                                  SourceLocation PragmaLoc,<br>
                                  MSVtorDispAttr::Mode Mode) {<br>
-  switch (Kind) {<br>
-  case PVDK_Set:<br>
-    VtorDispModeStack.back() = Mode;<br>
-    break;<br>
-  case PVDK_Push:<br>
-    VtorDispModeStack.push_back(Mode);<br>
-    break;<br>
-  case PVDK_Reset:<br>
-    VtorDispModeStack.clear();<br>
-    VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode));<br>
-    break;<br>
-  case PVDK_Pop:<br>
-    VtorDispModeStack.pop_back();<br>
-    if (VtorDispModeStack.empty()) {<br>
-      Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"<br>
-                                                    << "stack empty";<br>
-      VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode));<br>
-    }<br>
-    break;<br>
-  }<br>
+  if (Action & PSK_Pop && VtorDispStack.Stack.empty())<br>
+    Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"<br>
+                                                  << "stack empty";<br>
+  VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode);<br>
 }<br>
<br>
 template<typename ValueType><br>
@@ -323,7 +307,7 @@ void Sema::PragmaStack<ValueType>::Act(S<br>
                                        llvm::StringRef StackSlotLabel,<br>
                                        ValueType Value) {<br>
   if (Action == PSK_Reset) {<br>
-    CurrentValue = nullptr;<br>
+    CurrentValue = DefaultValue;<br>
     return;<br>
   }<br>
   if (Action & PSK_Push)<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/sections.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/sections.cpp?rev=267866&r1=267865&r2=267866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/sections.cpp?rev=267866&r1=267865&r2=267866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/sections.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/sections.cpp Thu Apr 28 05:13:18 2016<br>
@@ -31,6 +31,31 @@ int TEST1;<br>
 #pragma bss_seg(pop)<br>
 int TEST2;<br>
<br>
+<br>
+// Check "save-restore" of pragma stacks.<br>
+struct Outer {<br>
+  void f() {<br>
+    #pragma bss_seg(push, ".bss3")<br>
+    #pragma code_seg(push, ".my_code1")<br>
+    #pragma const_seg(push, ".my_const1")<br>
+    #pragma data_seg(push, ".data3")<br>
+    struct Inner {<br>
+      void g() {<br>
+        #pragma bss_seg(push, ".bss4")<br>
+        #pragma code_seg(push, ".my_code2")<br>
+        #pragma const_seg(push, ".my_const2")<br>
+        #pragma data_seg(push, ".data4")<br>
+      }<br>
+    };<br>
+  }<br>
+};<br>
+<br>
+void h2(void) {} // should be in ".my_code"<br>
+int TEST3; // should be in ".bss1"<br>
+int d2 = 1; // should be in ".data"<br>
+extern const int b2; // should be in ".my_const"<br>
+const int b2 = 1;<br>
+<br>
 #pragma section("read_flag_section", read)<br>
 // Even though they are not declared const, these become constant since they are<br>
 // in a read-only section.<br>
@@ -63,6 +88,9 @@ __declspec(allocate("short_section")) sh<br>
 //CHECK: @i = global i32 0<br>
 //CHECK: @TEST1 = global i32 0<br>
 //CHECK: @TEST2 = global i32 0, section ".bss1"<br>
+//CHECK: @TEST3 = global i32 0, section ".bss1"<br>
+//CHECK: @d2 = global i32 1, section ".data"<br>
+//CHECK: @b2 = constant i32 1, section ".my_const"<br>
 //CHECK: @unreferenced = constant i32 0, section "read_flag_section"<br>
 //CHECK: @referenced = constant i32 42, section "read_flag_section"<br>
 //CHECK: @implicitly_read_write = global i32 42, section "no_section_attributes"<br>
@@ -70,3 +98,4 @@ __declspec(allocate("short_section")) sh<br>
 //CHECK: @short_var = global i16 42, section "short_section"<br>
 //CHECK: define void @g()<br>
 //CHECK: define void @h() {{.*}} section ".my_code"<br>
+//CHECK: define void @h2() {{.*}} section ".my_code"<br>
<br>
Modified: cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp?rev=267866&r1=267865&r2=267866&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp?rev=267866&r1=267865&r2=267866&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp Thu Apr 28 05:13:18 2016<br>
@@ -22,7 +22,8 @@ struct B : virtual A { int b; };<br>
<br>
 // Test a reset.<br>
 #pragma vtordisp()<br>
-#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}<br>
+#pragma vtordisp(pop) // stack should NOT be affected by reset.<br>
+                      // Now stack contains '1'.<br>
<br>
 #pragma vtordisp(      // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}<br>
 #pragma vtordisp(asdf) // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}<br>
@@ -42,6 +43,7 @@ struct E {<br>
   virtual void f();<br>
 };<br>
<br>
+#pragma vtordisp(pop) // After this stack should be empty.<br>
 #pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}<br>
<br>
 void g() {<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>