]> granicus.if.org Git - clang/commitdiff
enforce requirements imposed by C90 6.8 TC1, fixing PR3919.
authorChris Lattner <sabre@nondot.org>
Sat, 18 Apr 2009 02:23:25 +0000 (02:23 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 18 Apr 2009 02:23:25 +0000 (02:23 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69415 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticLexKinds.td
lib/Lex/PPDirectives.cpp
test/Preprocessor/c90.c [new file with mode: 0644]

index 8d85637ea0a4f94d8236392266ac88d0fac2f87c..d87c89103612ead2e9ee969811182942153bb419 100644 (file)
@@ -95,6 +95,11 @@ def pp_include_macros_out_of_predefines : Error<
 def pp_include_next_absolute_path : Warning<"#include_next with absolute path">;
 def ext_c99_whitespace_required_after_macro_name : ExtWarn<
   "ISO C99 requires whitespace after the macro name">;
+def ext_missing_whitespace_after_macro_name : ExtWarn<
+  "whitespace required after macro name">;
+def warn_missing_whitespace_after_macro_name : Warning<
+  "whitespace required after macro name">;
+  
 def pp_pragma_once_in_main_file : Warning<"#pragma once in main file">;
 def pp_pragma_sysheader_in_main_file : Warning<
   "#pragma system_header ignored in main file">;
index be4da35f938d8442530a78c785b28694c8150881..e4b36fd15733d3496d4dc0c4c6de5eda96ccaf94 100644 (file)
@@ -1289,7 +1289,11 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) {
   // check other constraints on the first token of the macro body.
   if (Tok.is(tok::eom)) {
     // If there is no body to this macro, we have no special handling here.
-  } else if (Tok.is(tok::l_paren) && !Tok.hasLeadingSpace()) {
+  } else if (Tok.hasLeadingSpace()) {
+    // This is a normal token with leading space.  Clear the leading space
+    // marker on the first token to get proper expansion.
+    Tok.clearFlag(Token::LeadingSpace);
+  } else if (Tok.is(tok::l_paren)) {
     // This is a function-like macro definition.  Read the argument list.
     MI->setIsFunctionLike();
     if (ReadMacroDefinitionArgList(MI)) {
@@ -1303,19 +1307,30 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) {
 
     // Read the first token after the arg list for down below.
     LexUnexpandedToken(Tok);
-  } else if (!Tok.hasLeadingSpace()) {
+  } else if (Features.C99) {
     // C99 requires whitespace between the macro definition and the body.  Emit
     // a diagnostic for something like "#define X+".
-    if (Features.C99) {
-      Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
-    } else {
-      // FIXME: C90/C++ do not get this diagnostic, but it does get a similar
-      // one in some cases!
-    }
+    Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
   } else {
-    // This is a normal token with leading space.  Clear the leading space
-    // marker on the first token to get proper expansion.
-    Tok.clearFlag(Token::LeadingSpace);
+    // C90 6.8 TC1 says: "In the definition of an object-like macro, if the
+    // first character of a replacement list is not a character required by
+    // subclause 5.2.1, then there shall be white-space separation between the
+    // identifier and the replacement list.".  5.2.1 lists this set:
+    //   "A-Za-z0-9!"#%&'()*+,_./:;<=>?[\]^_{|}~" as well as whitespace, which
+    // is irrelevant here.
+    bool isInvalid = false;
+    if (Tok.is(tok::at)) // @ is not in the list above.
+      isInvalid = true;
+    else if (Tok.is(tok::unknown)) {
+      // If we have an unknown token, it is something strange like "`".  Since
+      // all of valid characters would have lexed into a single character
+      // token of some sort, we know this is not a valid case.
+      isInvalid = true;
+    }
+    if (isInvalid)
+      Diag(Tok, diag::ext_missing_whitespace_after_macro_name);
+    else
+      Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
   }
   
   // If this is a definition of a variadic C99 function-like macro, not using
diff --git a/test/Preprocessor/c90.c b/test/Preprocessor/c90.c
new file mode 100644 (file)
index 0000000..4287d0d
--- /dev/null
@@ -0,0 +1,10 @@
+/* RUN: clang-cc %s -std=c89 -Eonly -verify -pedantic-errors 
+ */
+
+/* PR3919 */
+
+#define foo`bar   /* expected-error {{whitespace required after macro name}} */
+#define foo2!bar  /* expected-warning {{whitespace required after macro name}} */
+
+#define foo3$bar  /* expected-error {{'$' in identifier}} */
+