]> granicus.if.org Git - clang/commitdiff
diagnose invalid syntax of STDC pragmas.
authorChris Lattner <sabre@nondot.org>
Sun, 19 Apr 2009 21:50:08 +0000 (21:50 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 19 Apr 2009 21:50:08 +0000 (21:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69554 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticLexKinds.td
lib/Lex/Pragma.cpp
test/Preprocessor/pragma_unknown.c

index cd59a1bfeb9a198e5e8293a68eec4d618bbc4f3c..8d6983122de3f8d0a9c99cb19ca4b214ec376a5e 100644 (file)
@@ -208,8 +208,12 @@ def warn_pragma_ignored : Warning<"unknown pragma ignored">,
    InGroup<UnknownPragmas>, DefaultIgnore;
 def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
    InGroup<UnknownPragmas>;
-
-  
+def ext_stdc_pragma_syntax :
+   ExtWarn<"expected 'ON' or 'OFF' or 'DEFAULT' in pragma">,
+   InGroup<UnknownPragmas>;
+def ext_stdc_pragma_syntax_eom :
+   ExtWarn<"expected end of macro in STDC pragma">,
+   InGroup<UnknownPragmas>;
 def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">;
 def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
 def err_paste_at_start : Error<
index 6e8c03db8a7dea6fe66fc09029d4444afa1e91e1..d30ff3c28976c71ce61d465ae6085068413238f1 100644 (file)
@@ -511,12 +511,48 @@ struct PragmaCommentHandler : public PragmaHandler {
 };
   
 // Pragma STDC implementations.
+
+enum STDCSetting {
+  STDC_ON, STDC_OFF, STDC_DEFAULT, STDC_INVALID
+};
+  
+static STDCSetting LexOnOffSwitch(Preprocessor &PP) {
+  Token Tok;
+  PP.LexUnexpandedToken(Tok);
+
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok, diag::ext_stdc_pragma_syntax);
+    return STDC_INVALID;
+  }
+  IdentifierInfo *II = Tok.getIdentifierInfo();
+  STDCSetting Result;
+  if (II->isStr("ON"))
+    Result = STDC_ON;
+  else if (II->isStr("OFF"))
+    Result = STDC_OFF;
+  else if (II->isStr("DEFAULT"))
+    Result = STDC_DEFAULT;
+  else {
+    PP.Diag(Tok, diag::ext_stdc_pragma_syntax);
+    return STDC_INVALID;
+  }
+
+  // Verify that this is followed by EOM.
+  PP.LexUnexpandedToken(Tok);
+  if (Tok.isNot(tok::eom))
+    PP.Diag(Tok, diag::ext_stdc_pragma_syntax_eom);
+  return Result;
+}
   
 /// PragmaSTDC_FP_CONTRACTHandler - "#pragma STDC FP_CONTRACT ...".
 struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler {
   PragmaSTDC_FP_CONTRACTHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
   virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
-    //PP.HandlePragmaFP_CONTRACT(CommentTok);
+    // We just ignore the setting of FP_CONTRACT. Since we don't do contractions
+    // at all, our default is OFF and setting it to ON is an optimization hint
+    // we can safely ignore.  When we support -ffma or something, we would need
+    // to diagnose that we are ignoring FMA.
+    LexOnOffSwitch(PP);
   }
 };
   
@@ -524,7 +560,7 @@ struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler {
 struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
   PragmaSTDC_FENV_ACCESSHandler(const IdentifierInfo *ID) : PragmaHandler(ID) {}
   virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
-    //PP.HandlePragmaFENV_ACCESS(CommentTok);
+    LexOnOffSwitch(PP);
   }
 };
   
@@ -533,7 +569,7 @@ struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
   PragmaSTDC_CX_LIMITED_RANGEHandler(const IdentifierInfo *ID)
     : PragmaHandler(ID) {}
   virtual void HandlePragma(Preprocessor &PP, Token &Tok) {
-    //PP.HandlePragmaCX_LIMITED_RANGE(CommentTok);
+    LexOnOffSwitch(PP);
   }
 };
   
@@ -541,6 +577,7 @@ struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
 struct PragmaSTDC_UnknownHandler : public PragmaHandler {
   PragmaSTDC_UnknownHandler() : PragmaHandler(0) {}
   virtual void HandlePragma(Preprocessor &PP, Token &UnknownTok) {
+    // C99 6.10.6p2, unknown forms are not allowed.
     PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
   }
 };
index 8ba0ea1d2ceff97881edd38d6e2522aa088424b8..d2738e5c7c38652deae83ebb3f78a51eccc4198c 100644 (file)
@@ -8,17 +8,20 @@
 #pragma STDC FP_CONTRACT ON
 #pragma STDC FP_CONTRACT OFF
 #pragma STDC FP_CONTRACT DEFAULT
-#pragma STDC FP_CONTRACT IN_BETWEEN
+#pragma STDC FP_CONTRACT IN_BETWEEN  // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}}
 
 #pragma STDC FENV_ACCESS ON
 #pragma STDC FENV_ACCESS OFF
 #pragma STDC FENV_ACCESS DEFAULT
-#pragma STDC FENV_ACCESS IN_BETWEEN
+#pragma STDC FENV_ACCESS IN_BETWEEN   // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}}
 
 #pragma STDC CX_LIMITED_RANGE ON
 #pragma STDC CX_LIMITED_RANGE OFF
 #pragma STDC CX_LIMITED_RANGE DEFAULT 
-#pragma STDC CX_LIMITED_RANGE IN_BETWEEN
+#pragma STDC CX_LIMITED_RANGE IN_BETWEEN   // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}}
+
+#pragma STDC CX_LIMITED_RANGE    // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}}
+#pragma STDC CX_LIMITED_RANGE ON FULL POWER  // expected-warning {{expected end of macro in STDC pragma}}
 
 #pragma STDC SO_GREAT  // expected-warning {{unknown pragma in STDC namespace}}
 #pragma STDC   // expected-warning {{unknown pragma in STDC namespace}}