diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-02-19 08:36:12 +0100 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-02-19 10:12:56 +0000 |
commit | b90f2fb251c20e75dd1d6e769098643a27864a96 (patch) | |
tree | 324a3b8fa2848289bf12843b40ed3bc3614405c7 /dist | |
parent | 41efaf1253b231834f0c5f1e33785dffa26defdf (diff) |
Clang: Fix crash in connect() statement
With this patch ClangCodeModel can properly
handle static overloads together with non-static ones.
Code completion still might crash - requires another patch.
Task-number: QTCREATORBUG-19184
Change-Id: I12f0e8cb56b3bed3f5ca1f7a9fe4ca3932b78125
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'dist')
-rw-r--r-- | dist/clang/patches/200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch | 148 | ||||
-rw-r--r-- | dist/clang/patches/README.md | 9 |
2 files changed, 157 insertions, 0 deletions
diff --git a/dist/clang/patches/200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch b/dist/clang/patches/200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch new file mode 100644 index 0000000000..3e5bfe553f --- /dev/null +++ b/dist/clang/patches/200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch @@ -0,0 +1,148 @@ +--- a/include/clang/Sema/Sema.h ++++ b/include/clang/Sema/Sema.h +@@ -2707,7 +2707,8 @@ + OverloadCandidateSet &CandidateSet, + TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, + bool SuppressUserConversions = false, +- bool PartialOverloading = false); ++ bool PartialOverloading = false, ++ bool FirstArgumentIsBase = false); + void AddMethodCandidate(DeclAccessPair FoundDecl, + QualType ObjectType, + Expr::Classification ObjectClassification, +--- a/lib/Sema/SemaCodeComplete.cpp ++++ b/lib/Sema/SemaCodeComplete.cpp +@@ -4396,9 +4396,11 @@ + ArgExprs.append(Args.begin(), Args.end()); + UnresolvedSet<8> Decls; + Decls.append(UME->decls_begin(), UME->decls_end()); ++ const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase(); + AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs, + /*SuppressUsedConversions=*/false, +- /*PartialOverloading=*/true); ++ /*PartialOverloading=*/true, ++ FirstArgumentIsBase); + } else { + FunctionDecl *FD = nullptr; + if (auto MCE = dyn_cast<MemberExpr>(NakedFn)) +--- a/lib/Sema/SemaOverload.cpp ++++ b/lib/Sema/SemaOverload.cpp +@@ -6343,24 +6343,36 @@ + OverloadCandidateSet& CandidateSet, + TemplateArgumentListInfo *ExplicitTemplateArgs, + bool SuppressUserConversions, +- bool PartialOverloading) { ++ bool PartialOverloading, ++ bool FirstArgumentIsBase) { + for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { + NamedDecl *D = F.getDecl()->getUnderlyingDecl(); + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { ++ ArrayRef<Expr *> FunctionArgs = Args; + if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) { + QualType ObjectType; + Expr::Classification ObjectClassification; +- if (Expr *E = Args[0]) { +- // Use the explit base to restrict the lookup: +- ObjectType = E->getType(); +- ObjectClassification = E->Classify(Context); +- } // .. else there is an implit base. ++ if (Args.size() > 0) { ++ if (Expr *E = Args[0]) { ++ // Use the explit base to restrict the lookup: ++ ObjectType = E->getType(); ++ ObjectClassification = E->Classify(Context); ++ } // .. else there is an implit base. ++ FunctionArgs = Args.slice(1); ++ } + AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(), + cast<CXXMethodDecl>(FD)->getParent(), ObjectType, +- ObjectClassification, Args.slice(1), CandidateSet, ++ ObjectClassification, FunctionArgs, CandidateSet, + SuppressUserConversions, PartialOverloading); + } else { +- AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet, ++ // Slice the first argument (which is the base) when we access ++ // static method as non-static ++ if (Args.size() > 0 && (!Args[0] || (FirstArgumentIsBase && isa<CXXMethodDecl>(FD) && ++ !isa<CXXConstructorDecl>(FD)))) { ++ assert(cast<CXXMethodDecl>(FD)->isStatic()); ++ FunctionArgs = Args.slice(1); ++ } ++ AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet, + SuppressUserConversions, PartialOverloading); + } + } else { +--- a/test/Index/complete-call.cpp ++++ b/test/Index/complete-call.cpp +@@ -94,6 +94,24 @@ + s.foo_7(42,); + } + ++struct Bar { ++ static void foo_1(); ++ void foo_1(float); ++ static void foo_1(int); ++}; ++ ++void test() { ++ Bar::foo_1(); ++ Bar b; ++ b.foo_1(); ++} ++ ++struct Bar2 : public Bar { ++ Bar2() { ++ Bar::foo_1(); ++ } ++}; ++ + // RUN: c-index-test -code-completion-at=%s:47:9 %s | FileCheck -check-prefix=CHECK-CC1 %s + // CHECK-CC1: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) + // CHECK-CC1: Completion contexts: +@@ -803,3 +821,46 @@ + // CHECK-CC59-NEXT: Class name + // CHECK-CC59-NEXT: Nested name specifier + // CHECK-CC59-NEXT: Objective-C interface ++ ++// RUN: c-index-test -code-completion-at=%s:104:14 %s | FileCheck -check-prefix=CHECK-CC60 %s ++// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) ++// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) ++// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) ++// CHECK-CC60: Completion contexts: ++// CHECK-CC60-NEXT: Any type ++// CHECK-CC60-NEXT: Any value ++// CHECK-CC60-NEXT: Enum tag ++// CHECK-CC60-NEXT: Union tag ++// CHECK-CC60-NEXT: Struct tag ++// CHECK-CC60-NEXT: Class name ++// CHECK-CC60-NEXT: Nested name specifier ++// CHECK-CC60-NEXT: Objective-C interface ++ ++// RUN: c-index-test -code-completion-at=%s:106:11 %s | FileCheck -check-prefix=CHECK-CC61 %s ++// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) ++// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) ++// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) ++// CHECK-CC61: Completion contexts: ++// CHECK-CC61-NEXT: Any type ++// CHECK-CC61-NEXT: Any value ++// CHECK-CC61-NEXT: Enum tag ++// CHECK-CC61-NEXT: Union tag ++// CHECK-CC61-NEXT: Struct tag ++// CHECK-CC61-NEXT: Class name ++// CHECK-CC61-NEXT: Nested name specifier ++// CHECK-CC61-NEXT: Objective-C interface ++ ++// RUN: c-index-test -code-completion-at=%s:111:16 %s | FileCheck -check-prefix=CHECK-CC62 %s ++// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1) ++// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1) ++// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1) ++// CHECK-CC62: Completion contexts: ++// CHECK-CC62-NEXT: Any type ++// CHECK-CC62-NEXT: Any value ++// CHECK-CC62-NEXT: Enum tag ++// CHECK-CC62-NEXT: Union tag ++// CHECK-CC62-NEXT: Struct tag ++// CHECK-CC62-NEXT: Class name ++// CHECK-CC62-NEXT: Nested name specifier ++// CHECK-CC62-NEXT: Objective-C interface ++ diff --git a/dist/clang/patches/README.md b/dist/clang/patches/README.md index 517df553b3..7c5da42036 100644 --- a/dist/clang/patches/README.md +++ b/dist/clang/patches/README.md @@ -112,3 +112,12 @@ Significantly reduces problems when saving a header file on Windows. Builds Clazy as an LLVM part and forces link for Clazy plugin registry entry. +##### 200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch + +* <https://reviews.llvm.org/D36390> +* <https://bugs.llvm.org/show_bug.cgi?id=33904> + +Fix overloaded static functions in SemaCodeComplete + +Happens when static function is accessed via the class variable. +That leads to incorrect overloads number because the variable is considered as the first argument. |