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,

llvm-svn: 352838
This commit is contained in:
Serge Guelton
2019-02-01 06:11:44 +00:00
parent 8a32f3b7a0
commit 5ef88bdb68
5 changed files with 64 additions and 1 deletions

View 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.

View File

@@ -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;
}

View File

@@ -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))

View File

@@ -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;
}

View File

@@ -0,0 +1,4 @@
extern int __isnanf(float f);
extern int __isnan(double f);
extern int __isnanl(long double f);
#define ISNAN isnan