From cb7fd3caeee52fe94461b717294c4db4056853e3 Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Fri, 1 Feb 2019 06:11:44 +0000 Subject: [PATCH 1/3] Fix isInSystemMacro to handle pasted macros Token pasted by the preprocessor (through ##) have a Spelling pointing to scratch buffer. As a result they are not recognized at system macro, even though the pasting happened in a system macro. Fix that by looking into the parent macro if the original lookup finds a scratch buffer. Differential Revision: https://reviews.llvm.org/D55782 This effectively fixes https://bugs.llvm.org/show_bug.cgi?id=35268, git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@352838 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/SourceManager.h | 18 +++++++++++++++++- test/Misc/no-warn-in-system-macro.c | 13 +++++++++++++ test/Misc/no-warn-in-system-macro.c.inc | 9 +++++++++ test/Misc/warn-in-system-macro-def.c | 21 +++++++++++++++++++++ test/Misc/warn-in-system-macro-def.c.inc | 4 ++++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 test/Misc/no-warn-in-system-macro.c create mode 100644 test/Misc/no-warn-in-system-macro.c.inc create mode 100644 test/Misc/warn-in-system-macro-def.c create mode 100644 test/Misc/warn-in-system-macro-def.c.inc diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index dcc4a37e23..c6b92f9000 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -1441,6 +1441,12 @@ public: return Filename.equals(""); } + /// Returns whether \p Loc is located in a file. + bool isWrittenInScratchSpace(SourceLocation Loc) const { + StringRef Filename(getPresumedLoc(Loc).getFilename()); + return Filename.equals(""); + } + /// Returns if a SourceLocation is in a system header. bool isInSystemHeader(SourceLocation Loc) const { return isSystem(getFileCharacteristic(Loc)); @@ -1453,7 +1459,17 @@ public: /// Returns whether \p Loc is expanded from a macro in a system header. bool isInSystemMacro(SourceLocation loc) const { - return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc)); + if(!loc.isMacroID()) + return false; + + // This happens when the macro is the result of a paste, in that case + // its spelling is the scratch memory, so we take the parent context. + if (isWrittenInScratchSpace(getSpellingLoc(loc))) { + return isInSystemHeader(getSpellingLoc(getImmediateMacroCallerLoc(loc))); + } + else { + return isInSystemHeader(getSpellingLoc(loc)); + } } /// The size of the SLocEntry that \p FID represents. diff --git a/test/Misc/no-warn-in-system-macro.c b/test/Misc/no-warn-in-system-macro.c new file mode 100644 index 0000000000..a319b14c9c --- /dev/null +++ b/test/Misc/no-warn-in-system-macro.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -isystem %S -Wdouble-promotion -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s +// CHECK-NOT: warning: + +#include + +int main(void) +{ + double foo = 1.0; + + if (isnan(foo)) + return 1; + return 0; +} diff --git a/test/Misc/no-warn-in-system-macro.c.inc b/test/Misc/no-warn-in-system-macro.c.inc new file mode 100644 index 0000000000..3cbe7dfc16 --- /dev/null +++ b/test/Misc/no-warn-in-system-macro.c.inc @@ -0,0 +1,9 @@ +extern int __isnanf(float f); +extern int __isnan(double f); +extern int __isnanl(long double f); +#define isnan(x) \ + (sizeof (x) == sizeof (float) \ + ? __isnanf (x) \ + : sizeof (x) == sizeof (double) \ + ? __isnan (x) : __isnanl (x)) + diff --git a/test/Misc/warn-in-system-macro-def.c b/test/Misc/warn-in-system-macro-def.c new file mode 100644 index 0000000000..b295130702 --- /dev/null +++ b/test/Misc/warn-in-system-macro-def.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -isystem %S -Wdouble-promotion -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s +// CHECK: warning: +// CHECK: expanded from macro 'ISNAN' +// CHECK: expanded from macro 'isnan' + +#include + +#define isnan(x) \ + (sizeof (x) == sizeof (float) \ + ? __isnanf (x) \ + : sizeof (x) == sizeof (double) \ + ? __isnan (x) : __isnanl (x)) + +int main(void) +{ + double foo = 1.0; + + if (ISNAN(foo)) + return 1; + return 0; +} diff --git a/test/Misc/warn-in-system-macro-def.c.inc b/test/Misc/warn-in-system-macro-def.c.inc new file mode 100644 index 0000000000..5c7e60275a --- /dev/null +++ b/test/Misc/warn-in-system-macro-def.c.inc @@ -0,0 +1,4 @@ +extern int __isnanf(float f); +extern int __isnan(double f); +extern int __isnanl(long double f); +#define ISNAN isnan -- 2.20.1