Clang used to reject consteval operators if they're used inside a
template due to TreeTransform putting two different DeclRefExpr
expressions for the same reference of the same operator declaration into
ReferenceToConsteval set.
It seems there was an attempt to not rebuild the whole operator that
never succeeded, so this patch just removes this attempt and
problemating referencing of a DeclRefExpr that always ended up
discarded.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
clang/lib/Sema/TreeTransform.h | ||
---|---|---|
11965–11968 | I don't understand why we would not need to transform the callee. do we do that elsewhere? |
clang/lib/Sema/TreeTransform.h | ||
---|---|---|
11965–11968 | For example, the code above for call and subscript operators never transforms the callee. |
Like @cor3ntin I'm concerned about removing the transform call. I'm just as concerned that it caused no regressions...
If we have to transform the arguments, then this can be a dependent thing, which means the callee should be possible to be dependent, right? Thus needs to be transformed somewhere?
Oh, I didn't get @cor3ntin 's question in the first place! The question was where the callee instantiated, right? The callee is instantiated when the whole operator call expr is rebuilt in Sema::RebuildCXXOperatorCallExpr. From what I see, Sema::RebuildCXXOperatorCallExpr doesn't really care which callee is passed there. It checks which operation it represents and performs lookup depending on the arguments. This triggers instantiation.
Please see the test I'm adding. There is several cases where the operator callee is dependent. They work fine with the change. I also see the instantiated function decl in the AST, just the same as before the change.
clang/lib/Sema/TreeTransform.h | ||
---|---|---|
11965–11968 | To me it looks like we need to transform the callee in order to transform the declarations in the UnresolvedLookupExpr, if the operator has such functions. For example, in: namespace A { template<typename T> T f(T t) { T operator+(T, T); return t + t; } } namespace B { struct X {}; } void g(B::X x) { A::f(x); } ... we need to transform the UnresolvedLookupExpr for the t + t to map from the operator+ declaration in the A::f template to the instantiated operator+ declaration in A::f<B::X>. But I think this patch is going in the right direction. We don't *actually* want to transform the callee; all we want to do is to transform the function or list of functions contained in the callee to form an UnresolvedSet of candidates found during the template parse. Building and then throwing away a DeclRefExpr or UnresolvedLookupExpr denoting that function or set of functions is both a waste of time and (as demonstrated by the bug being addressed here) problematic. Instead of calling TransformExpr on the callee, we should be calling TransformOverloadExprDecls if the callee is an UnresolvedLookupExpr or TransformDecl if it's a DeclRefExpr, and I think RebuildCXXOperatorCallExpr should be changed to take an UnresolvedSet and a RequiresADL flag, and it looks like we can then remove the OrigCallee parameter, if we pass in some extra source locations. |
clang/lib/Sema/TreeTransform.h | ||
---|---|---|
11965–11968 | Thank you for the feedback @rsmith , I appreciate it very much. |
clang/lib/Sema/TreeTransform.h | ||
---|---|---|
12002 | Can Functions ever held more than one element here? |
clang/lib/Sema/TreeTransform.h | ||
---|---|---|
12002 | Good catch! I don't think that more than one element can happen here. |
clang/lib/Sema/TreeTransform.h | ||
---|---|---|
11988–12014 | I don't think this is useful, it is only used L11999 but not in L11994, and in either cases you can use ULE->requiresADL() | |
12015 | here i think RequiresADL is always false | |
15214–15219 | Maybe it would be worth investigating that further before merging the PR? Although the pr is a clear improvement so I'll let you decide what to do! |
clang/lib/Sema/TreeTransform.h | ||
---|---|---|
15214–15219 | I've noticed that it is likely a dead code, so I didn't want to pass more parameters to RebuildCXXOperatorCallExpr in order to support dead code, but didn't feel confident enough to remove it. So I left this FIXME. |
clang/lib/Sema/TreeTransform.h | ||
---|---|---|
15214–15219 | I think you are right, It's seems like something I should have done as part of rGc1512250960bd247519a9f959ad4af202402dcc4. It think you should remove it. (if we break something we can put it back with tests!) |
I don't understand why we would not need to transform the callee. do we do that elsewhere?