r354162 - [MSVC] Recognize `static_assert` keyword in C and C++98

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 15 11:59:45 PST 2019


Author: rnk
Date: Fri Feb 15 11:59:45 2019
New Revision: 354162

URL: http://llvm.org/viewvc/llvm-project?rev=354162&view=rev
Log:
[MSVC] Recognize `static_assert` keyword in C and C++98

Summary:
The main effect is that clang now accepts the following conforming C11
code with MSVC headers:
  #include <assert.h>
  static_assert(1, "true");

This is a non-conforming extension (the keyword is outside the
implementer's namespace), so it is placed under -fms-compatibility
instead of -fms-extensions like most MSVC-specific keyword extensions.

Normally, in C11, the compiler is supposed to provide the _Static_assert
keyword, and assert.h should define static_assert to _Static_assert.
However, that is not what MSVC does, and MSVC doesn't even provide
_Static_assert.

This also has the less important side effect of enabling static_assert
in C++98 mode with -fms-compatibility. It's exceptionally difficult to
use modern MSVC headers without C++14 even, so this is relatively
unimportant.

Fixes PR26672

Patch by Andrey Bokhanko!

Reviewers: rsmith, thakis

Subscribers: cfe-commits, STL_MSFT

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

Modified:
    cfe/trunk/include/clang/Basic/TokenKinds.def
    cfe/trunk/lib/Basic/IdentifierTable.cpp
    cfe/trunk/test/Lexer/keywords_test.c
    cfe/trunk/test/Lexer/keywords_test.cpp

Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=354162&r1=354161&r2=354162&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Fri Feb 15 11:59:45 2019
@@ -243,6 +243,7 @@ PUNCTUATOR(caretcaret,            "^^")
 //                are enabled.
 //   KEYGNU   - This is a keyword if GNU extensions are enabled
 //   KEYMS    - This is a keyword if Microsoft extensions are enabled
+//   KEYMSCOMPAT - This is a keyword if Microsoft compatibility mode is enabled
 //   KEYNOMS18 - This is a keyword that must never be enabled under
 //               MSVC <= v18.
 //   KEYOPENCLC   - This is a keyword in OpenCL C
@@ -363,7 +364,7 @@ CXX11_KEYWORD(constexpr             , 0)
 CXX11_KEYWORD(decltype              , 0)
 CXX11_KEYWORD(noexcept              , 0)
 CXX11_KEYWORD(nullptr               , 0)
-CXX11_KEYWORD(static_assert         , 0)
+CXX11_KEYWORD(static_assert         , KEYMSCOMPAT)
 CXX11_KEYWORD(thread_local          , 0)
 
 // C++2a / concepts TS keywords

Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/IdentifierTable.cpp?rev=354162&r1=354161&r2=354162&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/lib/Basic/IdentifierTable.cpp Fri Feb 15 11:59:45 2019
@@ -99,6 +99,7 @@ namespace {
     KEYMODULES    = 0x100000,
     KEYCXX2A      = 0x200000,
     KEYOPENCLCXX  = 0x400000,
+    KEYMSCOMPAT   = 0x800000,
     KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX2A,
     KEYALL = (0xffffff & ~KEYNOMS18 &
               ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude.
@@ -125,6 +126,7 @@ static KeywordStatus getKeywordStatus(co
   if (LangOpts.C99 && (Flags & KEYC99)) return KS_Enabled;
   if (LangOpts.GNUKeywords && (Flags & KEYGNU)) return KS_Extension;
   if (LangOpts.MicrosoftExt && (Flags & KEYMS)) return KS_Extension;
+  if (LangOpts.MSVCCompat && (Flags & KEYMSCOMPAT)) return KS_Enabled;
   if (LangOpts.Borland && (Flags & KEYBORLAND)) return KS_Extension;
   if (LangOpts.Bool && (Flags & BOOLSUPPORT)) return KS_Enabled;
   if (LangOpts.Half && (Flags & HALFSUPPORT)) return KS_Enabled;

Modified: cfe/trunk/test/Lexer/keywords_test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/keywords_test.c?rev=354162&r1=354161&r2=354162&view=diff
==============================================================================
--- cfe/trunk/test/Lexer/keywords_test.c (original)
+++ cfe/trunk/test/Lexer/keywords_test.c Fri Feb 15 11:59:45 2019
@@ -7,7 +7,7 @@
 // RUN: %clang_cc1 -std=gnu89 -fno-gnu-keywords -E %s -o - \
 // RUN:     | FileCheck --check-prefix=CHECK-NONE %s
 
-// RUN: %clang_cc1 -std=c99 -fms-extensions -E %s -o - \
+// RUN: %clang_cc1 -std=c99 -fms-extensions -fms-compatibility -E %s -o - \
 // RUN:     | FileCheck --check-prefix=CHECK-MS-KEYWORDS %s
 // RUN: %clang_cc1 -std=c99 -fdeclspec -E %s -o - \
 // RUN:     | FileCheck --check-prefix=CHECK-DECLSPEC-KEYWORD %s
@@ -42,3 +42,13 @@ void no_declspec();
 #else
 void has_declspec();
 #endif
+
+// CHECK-NONE: no_static_assert
+// CHECK-GNU-KEYWORDS: no_static_assert
+// CHECK-MS-KEYWORDS: has_static_assert
+// CHECK-MS-KEYWORDS-WITHOUT-DECLSPEC: no_static_assert
+#if __is_identifier(static_assert)
+void no_static_assert();
+#else
+void has_static_assert();
+#endif

Modified: cfe/trunk/test/Lexer/keywords_test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/keywords_test.cpp?rev=354162&r1=354161&r2=354162&view=diff
==============================================================================
--- cfe/trunk/test/Lexer/keywords_test.cpp (original)
+++ cfe/trunk/test/Lexer/keywords_test.cpp Fri Feb 15 11:59:45 2019
@@ -11,9 +11,9 @@
 // RUN: %clang_cc1 -std=c++03 -fdeclspec -fno-declspec -fsyntax-only %s
 // RUN: %clang_cc1 -std=c++03 -fms-extensions -fno-declspec -fdeclspec -DDECLSPEC -fsyntax-only %s
 // RUN: %clang_cc1 -std=c++03 -fms-extensions -fdeclspec -fno-declspec -fsyntax-only %s
-// RUN: %clang -std=c++03 -target i686-windows-msvc -DDECLSPEC -fsyntax-only %s
+// RUN: %clang -std=c++03 -target i686-windows-msvc -DMS -DDECLSPEC -fsyntax-only %s
 // RUN: %clang -std=c++03 -target x86_64-scei-ps4 -DDECLSPEC -fsyntax-only %s
-// RUN: %clang -std=c++03 -target i686-windows-msvc -fno-declspec -fsyntax-only %s
+// RUN: %clang -std=c++03 -target i686-windows-msvc -DMS -fno-declspec -fsyntax-only %s
 // RUN: %clang -std=c++03 -target x86_64-scei-ps4 -fno-declspec -fsyntax-only %s
 
 #define IS_KEYWORD(NAME) _Static_assert(!__is_identifier(NAME), #NAME)
@@ -51,7 +51,12 @@ CXX11_KEYWORD(char32_t);
 CXX11_TYPE(char32_t);
 CXX11_KEYWORD(constexpr);
 CXX11_KEYWORD(noexcept);
+#ifndef MS
 CXX11_KEYWORD(static_assert);
+#else
+// MS compiler recognizes static_assert in all modes. So should we.
+IS_KEYWORD(static_assert);
+#endif
 CXX11_KEYWORD(thread_local);
 
 // Concepts TS keywords




More information about the cfe-commits mailing list