]> granicus.if.org Git - clang/commitdiff
MS static locals mangling: don't double-increment mangling number for switches
authorHans Wennborg <hans@hanshq.net>
Tue, 17 Jun 2014 00:09:05 +0000 (00:09 +0000)
committerHans Wennborg <hans@hanshq.net>
Tue, 17 Jun 2014 00:09:05 +0000 (00:09 +0000)
Differential Revision: http://reviews.llvm.org/D4165

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

lib/Parse/ParseStmt.cpp
test/CodeGenCXX/microsoft-abi-static-initializers.cpp

index da26853d4c485c7d18dde052dac1f3ef20dd2b84..059c2b6a3f8bc93d0cbd27de5634b42f8b2e0003 100644 (file)
@@ -1233,6 +1233,11 @@ StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
   getCurScope()->AddFlags(Scope::BreakScope);
   ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
 
+  // We have incremented the mangling number for the SwitchScope and the
+  // InnerScope, which is one too many.
+  if (C99orCXX)
+    getCurScope()->decrementMSLocalManglingNumber();
+
   // Read the body statement.
   StmtResult Body(ParseStatement(TrailingElseLoc));
 
index e96a5edd65409a3ad47943ed48be306ea61bc700..b353d0c9c2c7591b40ab0d6466cf3004923a2a92 100644 (file)
@@ -162,12 +162,41 @@ struct T {
   }
 };
 
+inline int switch_test(int x) {
+  // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test@@YAHH@Z"(i32 %x)
+  switch (x) {
+    static int a;
+    // CHECK: @"\01?a@?3??switch_test@@YAHH@Z@4HA"
+    case 0:
+      a++;
+      return 1;
+    case 1:
+      static int b;
+      // CHECK: @"\01?b@?3??switch_test@@YAHH@Z@4HA"
+      return b++;
+    case 2: {
+      static int c;
+      // CHECK: @"\01?c@?4??switch_test@@YAHH@Z@4HA"
+      return b + c++;
+    }
+  };
+}
+
+int f();
+inline void switch_test2() {
+  // CHECK-LABEL: define linkonce_odr void @"\01?switch_test2@@YAXXZ"()
+  // CHECK: @"\01?x@?2??switch_test2@@YAXXZ@4HA"
+  switch (1) default: static int x = f();
+}
+
 void force_usage() {
   UnreachableStatic();
   getS();
   (void)B<int>::foo;  // (void) - force usage
   enum_in_function();
   (void)&T::enum_in_struct;
+  switch_test(1);
+  switch_test2();
 }
 
 // CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"()