From: Chris Lattner Date: Sun, 19 Apr 2009 21:50:08 +0000 (+0000) Subject: diagnose invalid syntax of STDC pragmas. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6c5cf4a2e234923ab66127de0874a71cb6bfdd83;p=clang diagnose invalid syntax of STDC pragmas. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69554 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index cd59a1bfeb..8d6983122d 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -208,8 +208,12 @@ def warn_pragma_ignored : Warning<"unknown pragma ignored">, InGroup, DefaultIgnore; def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">, InGroup; - - +def ext_stdc_pragma_syntax : + ExtWarn<"expected 'ON' or 'OFF' or 'DEFAULT' in pragma">, + InGroup; +def ext_stdc_pragma_syntax_eom : + ExtWarn<"expected end of macro in STDC pragma">, + InGroup; 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< diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 6e8c03db8a..d30ff3c289 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -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); } }; diff --git a/test/Preprocessor/pragma_unknown.c b/test/Preprocessor/pragma_unknown.c index 8ba0ea1d2c..d2738e5c7c 100644 --- a/test/Preprocessor/pragma_unknown.c +++ b/test/Preprocessor/pragma_unknown.c @@ -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}}