[PATCH] D49091: Warn about usage of __has_include/__has_include_next in macro expansions
Alexander Richardson via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 9 10:53:05 PDT 2018
arichardson created this revision.
arichardson added a reviewer: rsmith.
Herald added a subscriber: cfe-commits.
The characters after '__has_include(' have special lexing rules that can't
possibly be applied when __has_include is generated by a macro. Instead of
wrapping __has_include in another macro the following should be used instead:
#ifndef __has_include
#define __has_include(...) 0
#endif
This warning should fix the underlying issue for https://llvm.org/pr37990
Repository:
rC Clang
https://reviews.llvm.org/D49091
Files:
include/clang/Basic/DiagnosticLexKinds.td
lib/Lex/PPMacroExpansion.cpp
test/Preprocessor/expr_has_include_expansion.c
Index: test/Preprocessor/expr_has_include_expansion.c
===================================================================
--- /dev/null
+++ test/Preprocessor/expr_has_include_expansion.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -E -verify -o /dev/null
+
+#define __libcpp_has_include(x) __has_include(x)
+#if __libcpp_has_include(<chrono>) // expected-warning{{macro expansion producing '__has_include' has undefined behavior}}
+#endif
+
+#define QT_HAS_INCLUDE_NEXT(x) __has_include_next(x)
+#if QT_HAS_INCLUDE_NEXT(<sys/foo.h>) // expected-warning{{macro expansion producing '__has_include_next' has undefined behavior}} expected-warning{{#include_next in primary source file}}
+#endif
+
+#define HAS_CHRONO __has_include(<chrono>)
+#if HAS_CHRONO // expected-warning{{macro expansion producing '__has_include' has undefined behavior}}
+#endif
+
+#define HAS_QUOTED_NEXT __has_include_next("foo.h")
+#if HAS_QUOTED_NEXT // expected-warning{{macro expansion producing '__has_include_next' has undefined behavior}} expected-warning{{#include_next in primary source file}}
+#endif
+
+// check that this diagnostic doesn't warn on normal __has_include() usage
+#if __has_include("foo.h") || __has_include_next("bar.h") // expected-warning{{#include_next in primary source file}}
+#endif
Index: lib/Lex/PPMacroExpansion.cpp
===================================================================
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -1182,6 +1182,12 @@
}
}
+ if (LParenLoc.isMacroID())
+ // The characters after '__has_include(' have special lexing rules that
+ // can't possibly be applied when __has_include is generated by a macro.
+ // Diagnose this to avoid problems such as https://llvm.org/pr37990
+ PP.Diag(LParenLoc, diag::warn_has_include_in_macro_expansion) << II;
+
// Reserve a buffer to get the spelling.
SmallString<128> FilenameBuffer;
StringRef Filename;
Index: include/clang/Basic/DiagnosticLexKinds.td
===================================================================
--- include/clang/Basic/DiagnosticLexKinds.td
+++ include/clang/Basic/DiagnosticLexKinds.td
@@ -771,6 +771,11 @@
"macro expansion producing 'defined' has undefined behavior">,
InGroup<ExpansionToDefined>;
+def warn_has_include_in_macro_expansion : Warning<
+ "macro expansion producing %0 has undefined behavior">,
+InGroup<DiagGroup<"expansion-to-has-include">>;
+
+
let CategoryName = "Nullability Issue" in {
def err_pp_assume_nonnull_syntax : Error<"expected 'begin' or 'end'">;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49091.154644.patch
Type: text/x-patch
Size: 2541 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180709/73b63208/attachment.bin>
More information about the cfe-commits
mailing list