summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2016-09-22 08:50:43 +0200
committerStephan Bergmann <sbergman@redhat.com>2016-09-22 08:50:43 +0200
commit4c70a1a6666a079872b8f1966bd398e924dc1d1a (patch)
tree0215f94340e0d86c4e0a422fb45ddfdb9ee3769d /compilerplugins
parentb078e0d638514b298616838fae090b8294bac32f (diff)
Check harder whether file is really under WORKDIR
1977b57bc9aaea71252358fa502110c348153c70 "vcl: loplugin:override" had only hit in out-of-tree builds, where the #include in the generated workdir/CustomTarget/vcl/unx/kde4/tst_exclude_socket_notifiers.moc is an absolute path. For in-tree builds, the generated #include line is "../../../../../vcl/unx/kde4/tst_exclude_socket_notifiers.hxx", so the returned getFileName() is .../workdir/../../../../../vcl/..., so was erroneously considered to be under WORKDIR. Change-Id: I9abef04b90ecb4921087a53ff196b833940085e5
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/plugin.cxx45
1 files changed, 44 insertions, 1 deletions
diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx
index 31648a5f9d2c..9f13ee7441b9 100644
--- a/compilerplugins/clang/plugin.cxx
+++ b/compilerplugins/clang/plugin.cxx
@@ -12,6 +12,7 @@
#include "plugin.hxx"
#include <cassert>
+#include <string>
#include <clang/Basic/FileManager.h>
#include <clang/Lex/Lexer.h>
@@ -41,9 +42,51 @@ bool Plugin::ignoreLocation( SourceLocation loc )
return true;
const char* bufferName = compiler.getSourceManager().getPresumedLoc( expansionLoc ).getFilename();
if( bufferName == NULL
- || strncmp( bufferName, WORKDIR, strlen( WORKDIR )) == 0
|| strncmp( bufferName, SRCDIR "/external/", strlen( SRCDIR "/external/" )) == 0 )
return true;
+ if( strncmp( bufferName, WORKDIR, strlen( WORKDIR )) == 0 )
+ {
+ // workdir/CustomTarget/vcl/unx/kde4/tst_exclude_socket_notifiers.moc
+ // includes
+ // "../../../../../vcl/unx/kde4/tst_exclude_socket_notifiers.hxx",
+ // making the latter file erroneously match here; so strip any ".."
+ // segments:
+ if (strstr(bufferName, "/..") == nullptr) {
+ return true;
+ }
+ std::string s(bufferName);
+ for (std::string::size_type i = 0;;) {
+ i = s.find("/.", i);
+ if (i == std::string::npos) {
+ break;
+ }
+ if (i + 2 == s.length() || s[i + 2] == '/') {
+ s.erase(i, 2); // [AAA]/.[/CCC] -> [AAA][/CCC]
+ } else if (s[i + 2] == '.'
+ && (i + 3 == s.length() || s[i + 3] == '/'))
+ {
+ if (i == 0) { // /..[/CCC] -> /..[/CCC]
+ break;
+ }
+ auto j = s.rfind('/', i - 1);
+ if (j == std::string::npos) {
+ // BBB/..[/CCC] -> BBB/..[/CCC] (instead of BBB/../CCC ->
+ // CCC, to avoid wrong ../../CCC -> CCC; relative paths
+ // shouldn't happen anyway, and even if they did, wouldn't
+ // match against WORKDIR anyway, as WORKDIR should be
+ // absolute):
+ break;
+ }
+ s.erase(j, i + 3 - j); // AAA/BBB/..[/CCC] -> AAA[/CCC]
+ i = j;
+ } else {
+ i += 2;
+ }
+ }
+ if (strncmp(s.c_str(), WORKDIR, strlen(WORKDIR)) == 0) {
+ return true;
+ }
+ }
if( strncmp( bufferName, BUILDDIR, strlen( BUILDDIR )) == 0
|| strncmp( bufferName, SRCDIR, strlen( SRCDIR )) == 0 )
return false; // ok