[cfe-commits] r146765 - in /cfe/trunk: include/clang/Basic/DiagnosticLexKinds.td lib/Lex/PPDirectives.cpp test/Preprocessor/macro_arg_directive.c test/Preprocessor/macro_arg_directive.h
Richard Smith
richard-llvm at metafoo.co.uk
Fri Dec 16 14:50:02 PST 2011
Author: rsmith
Date: Fri Dec 16 16:50:01 2011
New Revision: 146765
URL: http://llvm.org/viewvc/llvm-project?rev=146765&view=rev
Log:
Don't allow #include (and its friends #import, #include_next and
#__include_macros) in the arguments of a function-style macro. Directives in the
arguments of such macros have undefined behaviour, and GCC does not correctly
support these cases. In some situations, this can lead to better diagnostics.
Added:
cfe/trunk/test/Preprocessor/macro_arg_directive.c
cfe/trunk/test/Preprocessor/macro_arg_directive.h
Modified:
cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
cfe/trunk/lib/Lex/PPDirectives.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=146765&r1=146764&r2=146765&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Fri Dec 16 16:50:01 2011
@@ -202,8 +202,10 @@
InGroup<CXX98CompatPedantic>, DefaultIgnore;
def ext_named_variadic_macro : Extension<
"named variadic macros are a GNU extension">, InGroup<VariadicMacros>;
+def err_embedded_include : Error<
+ "embedding a #%0 directive within macro arguments is not supported">;
def ext_embedded_directive : Extension<
- "embedding a directive within macro arguments is not portable">,
+ "embedding a directive within macro arguments has undefined behavior">,
InGroup<DiagGroup<"embedded-directive">>;
def ext_missing_varargs_arg : Extension<
"varargs argument missing, but tolerated as an extension">;
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=146765&r1=146764&r2=146765&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Dec 16 16:50:01 2011
@@ -577,9 +577,25 @@
// A(abc
// #warning blah
// def)
- // If so, the user is relying on non-portable behavior, emit a diagnostic.
- if (InMacroArgs)
+ // If so, the user is relying on undefined behavior, emit a diagnostic. Do
+ // not support this for #include-like directives, since that can result in
+ // terrible diagnostics, and does not work in GCC.
+ if (InMacroArgs) {
+ if (IdentifierInfo *II = Result.getIdentifierInfo()) {
+ switch (II->getPPKeywordID()) {
+ case tok::pp_include:
+ case tok::pp_import:
+ case tok::pp_include_next:
+ case tok::pp___include_macros:
+ Diag(Result, diag::err_embedded_include) << II->getName();
+ DiscardUntilEndOfDirective();
+ return;
+ default:
+ break;
+ }
+ }
Diag(Result, diag::ext_embedded_directive);
+ }
TryAgain:
switch (Result.getKind()) {
Added: cfe/trunk/test/Preprocessor/macro_arg_directive.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/macro_arg_directive.c?rev=146765&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/macro_arg_directive.c (added)
+++ cfe/trunk/test/Preprocessor/macro_arg_directive.c Fri Dec 16 16:50:01 2011
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// header1.h
+void fail(const char *);
+#define MUNCH(...) \
+ ({ int result = 0; __VA_ARGS__; if (!result) { fail(#__VA_ARGS__); }; result })
+
+static inline int f(int k) {
+ return MUNCH( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{returning 'void'}}
+ if (k < 3)
+ result = 24;
+ else if (k > 4)
+ result = k - 4;
+}
+
+#include "macro_arg_directive.h" // expected-error {{embedding a #include directive within macro arguments is not supported}}
+
+int g(int k) {
+ return f(k) + f(k-1));
+}
Added: cfe/trunk/test/Preprocessor/macro_arg_directive.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/macro_arg_directive.h?rev=146765&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/macro_arg_directive.h (added)
+++ cfe/trunk/test/Preprocessor/macro_arg_directive.h Fri Dec 16 16:50:01 2011
@@ -0,0 +1,9 @@
+// Support header for macro_arg_directive.c
+
+int n;
+
+struct S {
+ int k;
+};
+
+void g(int);
More information about the cfe-commits
mailing list