[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