[PATCH] D32949: [Lexer] Make __has_extension ignore -pedantic-errors inside system headers
Eric Fiselier via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sat May 6 17:17:56 PDT 2017
EricWF created this revision.
Libc++ needs to be able to detect and use certain language extensions inside the STL headers. However `__has_extension` currently return `0` when `-pedantic-errors` is specified. However libc++ can still safely use these extensions since `-pedantic-errors` is ignored within system headers.
This patch make `__has_extension` ignore `-pedantic-errors` when the expansion occurs in a system header.
https://reviews.llvm.org/D32949
Files:
docs/LanguageExtensions.rst
lib/Lex/PPMacroExpansion.cpp
test/Lexer/has_extension_system_header.cpp
test/Lexer/has_extension_system_header.h
Index: test/Lexer/has_extension_system_header.h
===================================================================
--- /dev/null
+++ test/Lexer/has_extension_system_header.h
@@ -0,0 +1,13 @@
+#pragma once
+
+static_assert(__has_extension(cxx_init_captures) == !Pedantic, "");
+static_assert(MY_HAS_EXT(cxx_init_captures) == !Pedantic, "");
+
+#pragma clang system_header
+
+// Test expansions from macros defined in system headers and used elsewhere.
+#define SYSTEM_HAS_EXT(ID) __has_extension(ID)
+
+static_assert(__has_extension(cxx_init_captures), "");
+static_assert(SYSTEM_HAS_EXT(cxx_init_captures), "");
+static_assert(MY_HAS_EXT(cxx_init_captures), "");
Index: test/Lexer/has_extension_system_header.cpp
===================================================================
--- /dev/null
+++ test/Lexer/has_extension_system_header.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -pedantic-errors -DIS_PEDANTIC %s
+
+#ifdef IS_PEDANTIC
+constexpr bool Pedantic = true;
+#else
+constexpr bool Pedantic = false;
+#endif
+
+// Test expansions from macros defined outside of system headers
+#define MY_HAS_EXT(ID) __has_extension(ID)
+
+#include "has_extension_system_header.h"
+
+static_assert(__has_extension(cxx_init_captures) == !Pedantic, "");
+static_assert(SYSTEM_HAS_EXT(cxx_init_captures) == !Pedantic, "");
+static_assert(MY_HAS_EXT(cxx_init_captures) == !Pedantic, "");
Index: lib/Lex/PPMacroExpansion.cpp
===================================================================
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -1271,14 +1271,15 @@
/// HasExtension - Return true if we recognize and implement the feature
/// specified by the identifier, either as an extension or a standard language
/// feature.
-static bool HasExtension(const Preprocessor &PP, StringRef Extension) {
+static bool HasExtension(const Preprocessor &PP, StringRef Extension,
+ bool IsInSystemHeader) {
if (HasFeature(PP, Extension))
return true;
// If the use of an extension results in an error diagnostic, extensions are
// effectively unavailable, so just return false here.
if (PP.getDiagnostics().getExtensionHandlingBehavior() >=
- diag::Severity::Error)
+ diag::Severity::Error && !IsInSystemHeader)
return false;
const LangOptions &LangOpts = PP.getLangOpts();
@@ -1730,7 +1731,9 @@
[this](Token &Tok, bool &HasLexedNextToken) -> int {
IdentifierInfo *II = ExpectFeatureIdentifierInfo(Tok, *this,
diag::err_feature_check_malformed);
- return II && HasExtension(*this, II->getName());
+ if (!II) return false;
+ bool IsInSystemHeader = SourceMgr.isInSystemHeader(Tok.getLocation());
+ return HasExtension(*this, II->getName(), IsInSystemHeader);
});
} else if (II == Ident__has_builtin) {
EvaluateFeatureLikeBuiltinMacro(OS, Tok, II, *this,
Index: docs/LanguageExtensions.rst
===================================================================
--- docs/LanguageExtensions.rst
+++ docs/LanguageExtensions.rst
@@ -89,6 +89,9 @@
// language extension in C++98.
#endif
+Note that Clang may need to change the language extensions it offers, including
+removing extensions completely.
+
.. _langext-has-feature-back-compat:
For backward compatibility, ``__has_feature`` can also be used to test
@@ -100,7 +103,8 @@
<AddressSanitizer>`.
If the ``-pedantic-errors`` option is given, ``__has_extension`` is equivalent
-to ``__has_feature``.
+to ``__has_feature`` unless the expansion is within a system header in which
+case ``-pedantic-errors`` has no effect.
The feature tag is described along with the language feature below.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32949.98085.patch
Type: text/x-patch
Size: 3796 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170507/342c4675/attachment.bin>
More information about the cfe-commits
mailing list