]> granicus.if.org Git - clang/commitdiff
Fix isInSystemMacro to handle pasted macros
authorSerge Guelton <sguelton@redhat.com>
Fri, 1 Feb 2019 06:11:44 +0000 (06:11 +0000)
committerSerge Guelton <sguelton@redhat.com>
Fri, 1 Feb 2019 06:11:44 +0000 (06:11 +0000)
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
test/Misc/no-warn-in-system-macro.c [new file with mode: 0644]
test/Misc/no-warn-in-system-macro.c.inc [new file with mode: 0644]
test/Misc/warn-in-system-macro-def.c [new file with mode: 0644]
test/Misc/warn-in-system-macro-def.c.inc [new file with mode: 0644]

index ba829a87733de399be4eaa85582598873aa89d94..b45357e6452ab2781f2159b4e48fc3687c6a5f40 100644 (file)
@@ -1440,6 +1440,12 @@ public:
     return Filename.equals("<command line>");
   }
 
+  /// Returns whether \p Loc is located in a <scratch space> file.
+  bool isWrittenInScratchSpace(SourceLocation Loc) const {
+    StringRef Filename(getPresumedLoc(Loc).getFilename());
+    return Filename.equals("<scratch space>");
+  }
+
   /// Returns if a SourceLocation is in a system header.
   bool isInSystemHeader(SourceLocation Loc) const {
     return isSystem(getFileCharacteristic(Loc));
@@ -1452,7 +1458,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 (file)
index 0000000..a319b14
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -isystem %S -Wdouble-promotion -fsyntax-only %s  2>&1 | FileCheck -allow-empty %s
+// CHECK-NOT: warning:
+
+#include <no-warn-in-system-macro.c.inc>
+
+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 (file)
index 0000000..3cbe7df
--- /dev/null
@@ -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 (file)
index 0000000..b295130
--- /dev/null
@@ -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 <warn-in-system-macro-def.c.inc>
+
+#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 (file)
index 0000000..5c7e602
--- /dev/null
@@ -0,0 +1,4 @@
+extern int __isnanf(float f);
+extern int __isnan(double f);
+extern int __isnanl(long double f);
+#define ISNAN isnan