Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std::source_location line number wrong when used as default argument value #56379

Closed
IGR2014 opened this issue Jul 5, 2022 · 26 comments
Closed
Assignees
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema"

Comments

@IGR2014
Copy link

IGR2014 commented Jul 5, 2022

Consider the following code snipet (CompilerExplorer link):

#include<source_location>
#include<iostream>

void test_source_location(std::source_location src = std::source_location::current()) {
    std::cout << "called at " << src.line() << "\n";
}

int main() {
    test_source_location();
}

The output results for Clang, GCC and MSVC (left-to-right) are:
image

As you can see - both GCC and MSVC reports function INVOCATION line number, while Clang report function DECLARATION-one

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 5, 2022

@llvm/issue-subscribers-c-20

@ilya-biryukov
Copy link
Contributor

I will take look at this

@aasimon
Copy link

aasimon commented Jul 31, 2022

I would love to help out on this task if I can. So let me know if there is anything I could do to help.

@ilya-biryukov
Copy link
Contributor

Progress update from me.
I have a half-working fix (D129488), but it breaks consteval functions (see comments).
@jacobsa was about to pick it up from there.

@ilya-biryukov
Copy link
Contributor

@aasimon we'll let you know if we don't make progress here, so you can pick it up.
Unless you feel really strongly about taking this over.

@aasimon
Copy link

aasimon commented Aug 2, 2022

@aasimon we'll let you know if we don't make progress here, so you can pick it up. Unless you feel really strongly about taking this over.

I hardly think I am qualified for taking over the task ;-) I was more referring to helping out with testing and such.

@jacobsa
Copy link
Contributor

jacobsa commented Aug 9, 2022

Just for the record, the standard does agree that the current behavior is incorrect. From [support.srcloc.cons]/2 in N4868:

Any call to current that appears as a default argument ([dcl.fct.default]), or as a subexpression thereof, should correspond to the location of the invocation of the function that uses the default argument ([expr.call]).

@ChuanqiXu9
Copy link
Member

Just for the record, the standard does agree that the current behavior is incorrect. From [support.srcloc.cons]/2 in N4868:

Any call to current that appears as a default argument ([dcl.fct.default]), or as a subexpression thereof, should correspond to the location of the invocation of the function that uses the default argument ([expr.call]).

Currently the wording is:

Any call to current that appears as a default member initializer ([class.mem]), or as a subexpression thereof, should correspond to the location of the constructor definition or aggregate initialization that uses the default member initializer.

But the example is not default member initializer.

@jacobsa
Copy link
Contributor

jacobsa commented Aug 9, 2022

I'm not sure what you mean. The sentence I quoted comes after the one you quoted, right?

@ChuanqiXu9
Copy link
Member

I'm not sure what you mean. The sentence I quoted comes after the one you quoted, right?

Yes, my bad for oversee.

oberrich added a commit to oberrich/win11-toggle-rounded-corners that referenced this issue Oct 1, 2022
- Removed non-standard extensions
- Workaround for llvm/llvm-project#56379
- Formatting
@cor3ntin
Copy link
Contributor

I'm currently working on implementing CWG2631 to resolve this issue.

@cor3ntin
Copy link
Contributor

I'm doing multiple things, all of which are probably necessary / useful

  • Implement CWG2631 by delaying immediate functions evaluation, and rebuilding expressions when they are used. I avoid rewriting when there is no immediate call. I suspect we will struggle properly rewriting lambdas, blocks...
  • Treat __builtin_source_location* as immediate "calls"
  • Instead of having overwriting scopes of default arguments , we need to keep track of the outermost default argument/init list
  • Then we should be able to remove the codegen code path for source location

@AaronBallman

@cor3ntin cor3ntin self-assigned this Oct 23, 2022
@jacobsa
Copy link
Contributor

jacobsa commented Oct 23, 2022

Thanks for looking. I should have updated above: I kind of gave up on this, because it's a little more involved than expected and I don't have a lot of experience within clang proper.

@ChuanqiXu9
Copy link
Member

@cor3ntin hi, although I didn't look the problems in detail, I believe the proper fix will address the issue too: #57459

Hope this helps.

@cor3ntin
Copy link
Contributor

@ChuanqiXu9 There is more work to be done for modules to support that, maybe you could take a look once my PR is merged?
I'm not familiar with how export / reachable works in clang

@ChuanqiXu9
Copy link
Member

maybe you could take a look once my PR is merged?

Sure. I looked at your WIP patches and it seems like more complex than I imaged. I imaged we'll transform the calls with default arguments to the general style. For example, https://godbolt.org/z/vx4x5Er8h I imaged with the imaged "proper" fix, the dumped AST would be:

BinaryOperator 0x561a91dfd9b0 <col:12, col:27> 'int' '+'
        |-CallExpr 0x561a91ddd8c0 <col:12, col:16> 'int'
        | |-ImplicitCastExpr 0x561a91ddd8a8 <col:12> 'int (*)(B)' <FunctionToPointerDecay>
        | | `-DeclRefExpr 0x561a91ddd830 <col:12> 'int (B)' lvalue Function 0x561a91ddd5b8 'foo' 'int (B)'
        | `-CXXTemporaryObjectExpr 0x561a91ddd8e8 <<invalid sloc>> 'B':'B'
        `-CallExpr 0x561a91dfd988 <col:20, col:27> 'int'
          |-ImplicitCastExpr 0x561a91dfd970 <col:20> 'int (*)(B)' <FunctionToPointerDecay>
          | `-DeclRefExpr 0x561a91dfd950 <col:20> 'int (B)' lvalue Function 0x561a91ddd5b8 'foo' 'int (B)'
          `-CXXTemporaryObjectExpr 0x561a91dfd920 <col:24, col:26> 'B':'B' 'void () noexcept' zeroing

Then we'll get things addressed correctly. But I may took things too easily. There may be more works on the module's semantics' side.

@cor3ntin
Copy link
Contributor

This will be fixed by https://reviews.llvm.org/D136554

@EugeneZelenko EugeneZelenko added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Oct 29, 2022
@llvmbot
Copy link
Collaborator

llvmbot commented Oct 29, 2022

@llvm/issue-subscribers-clang-frontend

@cor3ntin
Copy link
Contributor

cor3ntin commented Nov 4, 2022

This is now fixed on main.

@cor3ntin cor3ntin closed this as completed Nov 4, 2022
@aasimon
Copy link

aasimon commented Nov 7, 2022

This is awesome news :-D

Any idea which clang version the fix will end up being released in?

@AaronBallman
Copy link
Collaborator

Any idea which clang version the fix will end up being released in?

It's expected to be released in Clang 16.

@cor3ntin
Copy link
Contributor

cor3ntin commented Nov 9, 2022

Note that this was reverted temporarily as we found bugs in the fix, but we are still targeting Clang 16

@avikivity
Copy link

Please backport it to clang 15.0.x

@avikivity
Copy link

And, if the fix has not landed again, I suggest to re-open the bug.

@cor3ntin cor3ntin reopened this Dec 1, 2022
@cor3ntin
Copy link
Contributor

cor3ntin commented Dec 1, 2022

Alas, it's a pretty involved changed, both in the compiler and in the language, so it's not a great candidate for backporting.
I'm still working through a few issues but I'm hoping to be able to re-reland that shortly.

@jyknight
Copy link
Member

@cor3ntin re-landed it ca61961 a few days ago, looks like it's stick this time, so:
Fixed for Clang 16. 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema"
Projects
Status: Done
Development

No branches or pull requests