[clang] 6e51991 - [clang][AST] Handle overload callee type in CallExpr::getCallReturnType.
Balázs Kéri via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 12 00:33:14 PDT 2021
Author: Balázs Kéri
Date: 2021-04-12T09:44:17+02:00
New Revision: 6e5199104914c2415092315388ed09fbd9d629f7
URL: https://github.com/llvm/llvm-project/commit/6e5199104914c2415092315388ed09fbd9d629f7
DIFF: https://github.com/llvm/llvm-project/commit/6e5199104914c2415092315388ed09fbd9d629f7.diff
LOG: [clang][AST] Handle overload callee type in CallExpr::getCallReturnType.
The function did not handle every case. In some cases this
caused assertion failure.
After the fix the function returns DependentTy if the exact
return type can not be determined.
It seems that clang itself does not call the function in the
affected cases but some checker or other code may call it.
Reviewed By: hokein
Differential Revision: https://reviews.llvm.org/D95244
Added:
Modified:
clang/lib/AST/Expr.cpp
clang/unittests/Tooling/SourceCodeTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index eccb42eeb7e74..a4a70befbdb31 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1391,8 +1391,15 @@ QualType CallExpr::getCallReturnType(const ASTContext &Ctx) const {
if (isa<CXXPseudoDestructorExpr>(Callee->IgnoreParens()))
return Ctx.VoidTy;
+ if (isa<UnresolvedMemberExpr>(Callee->IgnoreParens()))
+ return Ctx.DependentTy;
+
// This should never be overloaded and so should never return null.
CalleeType = Expr::findBoundMemberType(Callee);
+ assert(!CalleeType.isNull());
+ } else if (CalleeType->isDependentType() ||
+ CalleeType->isSpecificPlaceholderType(BuiltinType::Overload)) {
+ return Ctx.DependentTy;
}
const FunctionType *FnType = CalleeType->castAs<FunctionType>();
diff --git a/clang/unittests/Tooling/SourceCodeTest.cpp b/clang/unittests/Tooling/SourceCodeTest.cpp
index eb652cf030644..badc6f88fc0af 100644
--- a/clang/unittests/Tooling/SourceCodeTest.cpp
+++ b/clang/unittests/Tooling/SourceCodeTest.cpp
@@ -621,4 +621,71 @@ int c = BAR 3.0;
};
Visitor.runOver(Code);
}
+
+TEST(SourceCodeTest, GetCallReturnType_Dependent) {
+ llvm::Annotations Code{R"cpp(
+template<class T, class F>
+void templ(const T& t, F f) {}
+
+template<class T, class F>
+void templ1(const T& t, F f) {
+ $test1[[f(t)]];
+}
+
+int f_overload(int) { return 1; }
+int f_overload(double) { return 2; }
+
+void f1() {
+ int i = 0;
+ templ(i, [](const auto &p) {
+ $test2[[f_overload(p)]];
+ });
+}
+
+struct A {
+ void f_overload(int);
+ void f_overload(double);
+};
+
+void f2() {
+ int i = 0;
+ templ(i, [](const auto &p) {
+ A a;
+ $test3[[a.f_overload(p)]];
+ });
+}
+)cpp"};
+
+ llvm::Annotations::Range R1 = Code.range("test1");
+ llvm::Annotations::Range R2 = Code.range("test2");
+ llvm::Annotations::Range R3 = Code.range("test3");
+
+ CallsVisitor Visitor;
+ Visitor.OnCall = [&R1, &R2, &R3](CallExpr *Expr, ASTContext *Context) {
+ unsigned Begin = Context->getSourceManager().getFileOffset(
+ Expr->getSourceRange().getBegin());
+ unsigned End = Context->getSourceManager().getFileOffset(
+ Expr->getSourceRange().getEnd());
+ llvm::Annotations::Range R{Begin, End + 1};
+
+ QualType CalleeType = Expr->getCallee()->getType();
+ if (R == R1) {
+ ASSERT_TRUE(CalleeType->isDependentType());
+ EXPECT_EQ(Expr->getCallReturnType(*Context), Context->DependentTy);
+ } else if (R == R2) {
+ ASSERT_FALSE(CalleeType->isDependentType());
+ ASSERT_TRUE(CalleeType->isSpecificPlaceholderType(BuiltinType::Overload));
+ ASSERT_TRUE(isa<UnresolvedLookupExpr>(Expr->getCallee()));
+ EXPECT_EQ(Expr->getCallReturnType(*Context), Context->DependentTy);
+ } else if (R == R3) {
+ ASSERT_FALSE(CalleeType->isDependentType());
+ ASSERT_TRUE(
+ CalleeType->isSpecificPlaceholderType(BuiltinType::BoundMember));
+ ASSERT_TRUE(isa<UnresolvedMemberExpr>(Expr->getCallee()));
+ EXPECT_EQ(Expr->getCallReturnType(*Context), Context->DependentTy);
+ }
+ };
+ Visitor.runOver(Code.code(), CallsVisitor::Lang_CXX14);
+}
+
} // end anonymous namespace
More information about the cfe-commits
mailing list