forked from qt-creator/qt-creator
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>
This commit is contained in:
148
dist/clang/patches/200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch
vendored
Normal file
148
dist/clang/patches/200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch
vendored
Normal file
@@ -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
|
||||
+
|
||||
9
dist/clang/patches/README.md
vendored
9
dist/clang/patches/README.md
vendored
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user