[PATCH] D95244: [clang][AST] Handle overload callee type in CallExpr::getCallReturnType.

Haojian Wu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 12 04:30:56 PST 2021


hokein added a comment.

This looks like a reasonable solution to me -- if we don't know the function call result type (e.g. dependent-type callExpr in template context), modeling it as a dependent type.



================
Comment at: clang/lib/AST/Expr.cpp:1387
+
+  auto CreateDependentType = [&Ctx]() {
+    ASTContext::GetBuiltinTypeError Error;
----------------
this can be removed, dependent type is a builtin type, so you could just use `Ctx.DependentTy`.


================
Comment at: clang/lib/AST/Expr.cpp:1403
     CalleeType = Expr::findBoundMemberType(Callee);
+    if (CalleeType.isNull())
+      return CreateDependentType();
----------------
The only case is `UnresolvedMemberExpr`, I think we'd keep the previous comment and special-case the UnresolvedMemberExpr (like the `CXXPseudoDestructorExpr` above).

```
if (isa<UnresolvedMemberExpr>(...))
  return Ctx.DependentTy;

 // This should never be overloaded and so should never return null.
 CalleeType = Expr::findBoundMemberType(Callee);
 CHECK(!CalleeType.isNull());
```


================
Comment at: clang/unittests/Tooling/SourceCodeTest.cpp:630
+  f(t);
+  // CalleeType in getCallReturntype is Overload and dependent
+}
----------------
CalleeType is not a specific term in `getCallReturnType`, just `CalleeType is overload and dependent`, I think we can also verify this in the Visitor.OnCall callback. 

IIUC, the patch fixes three different crashes
- calling getCallReturntype on the `f(t)` expr 
- calling getCallReturntype on the `f_overload()` expr 
- calling getCallReturntype on the `a.f_overload(p);` expr

I think it would be much clear to express them in the `OnCall` callback (rather than calling `getCallReturnType` on every Expr). One option is to use the annotation, and identify the expression by location like below. An other benefit is that we can unify the test code (instead of duplicating them) without hurting the code readability.

```
template<class T, class F>
void templ(const T& t, F f) {
  $crash1[[f]](t);
  // CalleeType in getCallReturntype is Overload and dependent
}

struct A {
  void f_overload(int);
  void f_overload(double);
};

void f() {
  int i = 0;
  templ(i, [](const auto &p) {
    $crash2[[f_overload]](p); // UnresolvedLookupExpr
    // CalleeType in getCallReturntype is Overload and not dependent
  });

  templ(i, [](const auto &p) {
    A a;
    a.$crash3[[f_overload]](p); // UnresolvedMemberExpr
    // CalleeType in getCallReturntype is BoundMember and has overloads
  });
  
}
```
 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95244/new/

https://reviews.llvm.org/D95244



More information about the cfe-commits mailing list