diff options
author | Alp Toker <alp@nuanti.com> | 2014-05-31 03:38:17 +0000 |
---|---|---|
committer | Alp Toker <alp@nuanti.com> | 2014-05-31 03:38:17 +0000 |
commit | 2c59df7b3ddf27b6ebbfc8a68f3831045e882c04 (patch) | |
tree | 8a0384dcf70961c9d966059d81ab0acde48bef37 | |
parent | 96dd0dfe842893651cdc6b377502685731183163 (diff) | |
download | clang-2c59df7b3ddf27b6ebbfc8a68f3831045e882c04.tar.gz clang-2c59df7b3ddf27b6ebbfc8a68f3831045e882c04.tar.bz2 clang-2c59df7b3ddf27b6ebbfc8a68f3831045e882c04.tar.xz |
Preprocessor: recover gracefully when C++ operator names are used as macro identifiers
This failure mode shows up occasionally when users try to include C headers in
C++ projects or when porting from Windows. We might as well recover in the way
the user expected, thus avoiding confusing diagnostic messages at point of use.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209963 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticLexKinds.td | 2 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 7 | ||||
-rw-r--r-- | test/Preprocessor/cxx_oper_keyword.cpp | 13 |
3 files changed, 16 insertions, 6 deletions
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 2d584f1c34..01f56089d9 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -500,7 +500,7 @@ def ext_pp_bad_paste_ms : ExtWarn< "pasting formed '%0', an invalid preprocessing token">, DefaultError, InGroup<DiagGroup<"invalid-token-paste">>; def err_pp_operator_used_as_macro_name : Error< - "C++ operator %0 (aka %1) cannot be used as a macro name">; + "C++ operator %0 (aka %1) used as a macro name">; def err_pp_illegal_floating_literal : Error< "floating point literal in preprocessor expression">; def err_pp_line_requires_integer : Error< diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 78b84e2d46..46e8f07c51 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -148,10 +148,11 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, char isDefineUndef) { if (!getLangOpts().MSVCCompat) // C++ 2.5p2: Alternative tokens behave the same as its primary token // except for their spellings. - return Diag(MacroNameTok, diag::err_pp_operator_used_as_macro_name) - << II << MacroNameTok.getKind(); + Diag(MacroNameTok, diag::err_pp_operator_used_as_macro_name) + << II << MacroNameTok.getKind(); - // Allow #defining |and| and friends for Microsoft compatibility. + // Allow #defining |and| and friends for Microsoft compatibility or + // recovery when legacy C headers are included in C++. MacroNameTok.setIdentifierInfo(II); } diff --git a/test/Preprocessor/cxx_oper_keyword.cpp b/test/Preprocessor/cxx_oper_keyword.cpp index 03e2a661b9..89a094d073 100644 --- a/test/Preprocessor/cxx_oper_keyword.cpp +++ b/test/Preprocessor/cxx_oper_keyword.cpp @@ -11,12 +11,21 @@ // Not valid in C++ unless -fno-operator-names is passed: #ifdef OPERATOR_NAMES -//expected-error@+2 {{C++ operator 'and' (aka '&&') cannot be used as a macro name}} +//expected-error@+2 {{C++ operator 'and' (aka '&&') used as a macro name}} #endif #define and foo #ifdef OPERATOR_NAMES -//expected-error@+2 {{C++ operator 'xor' (aka '^') cannot be used as a macro name}} +//expected-error@+2 {{C++ operator 'xor' (aka '^') used as a macro name}} #endif #if defined xor #endif + +// For error recovery we continue as though the identifier was a macro name regardless of -fno-operator-names. +#ifdef OPERATOR_NAMES +//expected-error@+3 {{C++ operator 'and' (aka '&&') used as a macro name}} +#endif +//expected-warning@+2 {{and is defined}} +#ifdef and +#warning and is defined +#endif |