Hi rsmith, rafael.espindola,
If the edit distance between the two macros is more than 50%, DefinedMacro may
not be header guard, or can be header guard of another header file, or it might
be defining something completely different. This can be observed in the wild
when handling feature macros or header guards in different files.
// foo.c
#ifndef NO_FLOATING_POINT_SUPPORT
#define USE_SOMETHING_ELSE
#include "foo.h"
/* ... */
#endif /* !defined(NO_FLOATING_POINT_SUPPORT)
http://llvm-reviews.chandlerc.com/D1506
Files:
lib/Lex/PPLexerChange.cpp
test/Lexer/header.cpp
test/Lexer/Inputs/unlikely-to-be-header-guard.h
Index: lib/Lex/PPLexerChange.cpp
===================================================================
--- lib/Lex/PPLexerChange.cpp
+++ lib/Lex/PPLexerChange.cpp
@@ -251,19 +251,36 @@
if (!ControllingMacro->hasMacroDefinition() &&
DefinedMacro != ControllingMacro &&
HeaderInfo.FirstTimeLexingFile(FE)) {
- // Emit a warning for a bad header guard.
- Diag(CurPPLexer->MIOpt.GetMacroLocation(),
- diag::warn_header_guard)
- << CurPPLexer->MIOpt.GetMacroLocation()
- << ControllingMacro;
- Diag(CurPPLexer->MIOpt.GetDefinedLocation(),
- diag::note_header_guard)
- << CurPPLexer->MIOpt.GetDefinedLocation()
- << DefinedMacro
- << ControllingMacro
- << FixItHint::CreateReplacement(
- CurPPLexer->MIOpt.GetDefinedLocation(),
- ControllingMacro->getName());
+
+ // If the edit distance between the two macros is more than 50%,
+ // DefinedMacro may not be header guard, or can be header guard of
+ // another header file. Therefore, it maybe defining something
+ // completely different. This can be observed in the wild when
+ // handling feature macros or header guards in different files.
+
+ const StringRef ControllingMacroName = ControllingMacro->getName();
+ const StringRef DefinedMacroName = DefinedMacro->getName();
+ const size_t MaxHalfLength = std::max(ControllingMacroName.size(),
+ DefinedMacroName.size()) / 2;
+ const unsigned ED = ControllingMacroName.edit_distance(
+
DefinedMacroName,
+ true,
+ MaxHalfLength);
+ if (ED <= MaxHalfLength) {
+ // Emit a warning for a bad header guard.
+ Diag(CurPPLexer->MIOpt.GetMacroLocation(),
+ diag::warn_header_guard)
+ << CurPPLexer->MIOpt.GetMacroLocation()
+ << ControllingMacro;
+ Diag(CurPPLexer->MIOpt.GetDefinedLocation(),
+ diag::note_header_guard)
+ << CurPPLexer->MIOpt.GetDefinedLocation()
+ << DefinedMacro
+ << ControllingMacro
+ << FixItHint::CreateReplacement(
+
CurPPLexer->MIOpt.GetDefinedLocation(),
+ ControllingMacro->getName());
+ }
}
}
}
Index: test/Lexer/header.cpp
===================================================================
--- test/Lexer/header.cpp
+++ test/Lexer/header.cpp
@@ -6,6 +6,7 @@
#include "Inputs/different-define.h"
#include "Inputs/out-of-order-define.h"
#include "Inputs/tokens-between-ifndef-and-define.h"
+#include "Inputs/unlikely-to-be-header-guard.h"
#include "Inputs/bad-header-guard.h"
// CHECK: In file included from {{.*}}header.cpp:{{[0-9]*}}:
Index: test/Lexer/Inputs/unlikely-to-be-header-guard.h
===================================================================
--- /dev/null
+++ test/Lexer/Inputs/unlikely-to-be-header-guard.h
@@ -0,0 +1,4 @@
+#ifndef data_rep_h
+#define use_alternate_data_rep
+/* #include "data_rep.h" */
+#endif
Index: lib/Lex/PPLexerChange.cpp
===================================================================
--- lib/Lex/PPLexerChange.cpp
+++ lib/Lex/PPLexerChange.cpp
@@ -251,19 +251,36 @@
if (!ControllingMacro->hasMacroDefinition() &&
DefinedMacro != ControllingMacro &&
HeaderInfo.FirstTimeLexingFile(FE)) {
- // Emit a warning for a bad header guard.
- Diag(CurPPLexer->MIOpt.GetMacroLocation(),
- diag::warn_header_guard)
- << CurPPLexer->MIOpt.GetMacroLocation()
- << ControllingMacro;
- Diag(CurPPLexer->MIOpt.GetDefinedLocation(),
- diag::note_header_guard)
- << CurPPLexer->MIOpt.GetDefinedLocation()
- << DefinedMacro
- << ControllingMacro
- << FixItHint::CreateReplacement(
- CurPPLexer->MIOpt.GetDefinedLocation(),
- ControllingMacro->getName());
+
+ // If the edit distance between the two macros is more than 50%,
+ // DefinedMacro may not be header guard, or can be header guard of
+ // another header file. Therefore, it maybe defining something
+ // completely different. This can be observed in the wild when
+ // handling feature macros or header guards in different files.
+
+ const StringRef ControllingMacroName = ControllingMacro->getName();
+ const StringRef DefinedMacroName = DefinedMacro->getName();
+ const size_t MaxHalfLength = std::max(ControllingMacroName.size(),
+ DefinedMacroName.size()) / 2;
+ const unsigned ED = ControllingMacroName.edit_distance(
+ DefinedMacroName,
+ true,
+ MaxHalfLength);
+ if (ED <= MaxHalfLength) {
+ // Emit a warning for a bad header guard.
+ Diag(CurPPLexer->MIOpt.GetMacroLocation(),
+ diag::warn_header_guard)
+ << CurPPLexer->MIOpt.GetMacroLocation()
+ << ControllingMacro;
+ Diag(CurPPLexer->MIOpt.GetDefinedLocation(),
+ diag::note_header_guard)
+ << CurPPLexer->MIOpt.GetDefinedLocation()
+ << DefinedMacro
+ << ControllingMacro
+ << FixItHint::CreateReplacement(
+ CurPPLexer->MIOpt.GetDefinedLocation(),
+ ControllingMacro->getName());
+ }
}
}
}
Index: test/Lexer/header.cpp
===================================================================
--- test/Lexer/header.cpp
+++ test/Lexer/header.cpp
@@ -6,6 +6,7 @@
#include "Inputs/different-define.h"
#include "Inputs/out-of-order-define.h"
#include "Inputs/tokens-between-ifndef-and-define.h"
+#include "Inputs/unlikely-to-be-header-guard.h"
#include "Inputs/bad-header-guard.h"
// CHECK: In file included from {{.*}}header.cpp:{{[0-9]*}}:
Index: test/Lexer/Inputs/unlikely-to-be-header-guard.h
===================================================================
--- /dev/null
+++ test/Lexer/Inputs/unlikely-to-be-header-guard.h
@@ -0,0 +1,4 @@
+#ifndef data_rep_h
+#define use_alternate_data_rep
+/* #include "data_rep.h" */
+#endif
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits