Open
Description
Code:
example1:
// calculate n!
constexpr auto foo(int n) {
if(n <= 1)
return 1;
return n * foo(n-1);
}
void bar() {
int k = foo(4); // get 12 here, it should be 24
}
example2:
constexpr auto foo(int n) {
if(n <= 1)
return 1;
int v = foo(n-1);
return n * v;
}
void bar() {
int k = foo(4); // get 24 here, correct
}
for the example1's code, printing function foo's binding in ASTPrinter(some changes in print()),i got this for return n * foo(n-1)
:
CPPASTReturnStatement@885851948<line:4>
CPPASTBinaryExpression@2048834776 type:Attempt to use symbol failed: foo op:1
CPPASTIdExpression@245475541 type:int
CPPASTName@22429093 n int null CPPParameter CPPBasicType
CPPASTFunctionCallExpression@733957003 type:Attempt to use symbol failed: foo
CPPASTIdExpression@815992954 type:ProblemType
CPPASTName@868737467 foo ProblemBinding Attempt to use symbol failed: foo
CDT can't deduce the right type for the name foo in ReturnStatement,after i debug the code,find out that CDT traverse AST and analyze ReturnStatements to deduce Return Type,at the same time it compute the binding in returnstmt.
So before CDT figure out foo's return type, it already set a ProblemBinding to the name foo in ReturnStatement, when we execute foo(4),it take out the binding directly and not calculate again because it uses cache.