-
Notifications
You must be signed in to change notification settings - Fork 13.4k
inherited constructor causes std::source_location::current()
to point at wrong line
#137907
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
Comments
@llvm/issue-subscribers-clang-frontend Author: None (snarkmaster)
In this code (https://godbolt.org/z/dPhq718e5), `Foo foo{}` ends up with an incorrect `source_location`, while `Foo foo{Potato{}` is fine.
It looks like I'm not a standards lawyer, but I didn't find any suggestion that what we're seeing here is the specified behavior. And for default arguments, the the clear intent of the C++ standard is for default arguments to be evaluated at the call site. The current behavior violates at least the spirit of that rule. It also breaks the typical
|
source_locationI::current()
to point at wrong linestd::source_location::current()
to point at wrong line
I think clang and gcc are correct here. struct Bar {
int sl;
Bar(int i = 0, int sl = __builtin_LINE()) : sl(sl) {}
};
struct Foo : Bar {
using Bar::Bar;
};
int main() {
Foo foo; // #1
return foo.sl;
} Per https://eel.is/c++draft/class#inhctor.init-1.sentence-1
In If instead you give parameters, the constructor of |
I think the next few sentences suggest a different interpretation, and this Godbolt shows Clang violates my understanding of those sentences. Per https://eel.is/c++draft/class#inhctor.init-1.sentence-3
Taking @snarkmaster's sample code and extending it by giving
(see this Godbolt for a working example) The above code generates the following for the
I believe that, in this case, the I'm a beginner language lawyer so I'm not completely confident in my interpretation. Have I misunderstood? If I've understood correctly then my further interpretation of [class.inhctor.init] is that, for the initialization of the parameters to the inherited constructor to be definitely initialized before any part of the D object, the parameters must be initialized, in this case, at the call site of |
I think really, there's an issue here with the implicit declaration of default constructors. Consider the following variation:
This "works" in MSVC; I think this is because it suppresses Foo's default constructor? On clang and gcc, this has no effect. In clang's AST, there's a declaration of an implicit default constructor. Or another variation:
This "works" in all three compilers, because it suppresses the default constructor. This doesn't seem intentional... or at least if it is intentional, I can't find any language supporting it. |
Whether we declare an implicit default constructor is observable in other ways; for example:
|
In this code (https://godbolt.org/z/dPhq718e5),
Foo foo{}
ends up with an incorrectsource_location
, whileFoo foo{Potato{}
is fine.It looks like
using Bar::Bar
generates a default ctor forFoo
, which becomes the evaluation site forsource_location::current()
.I'm not a standards lawyer, but I didn't find any suggestion that what we're seeing here is the specified behavior. And for default arguments, the the clear intent of the C++ standard is for default arguments to be evaluated at the call site. The current behavior violates at least the spirit of that rule. It also breaks the typical
source_location
-stamping technique.The text was updated successfully, but these errors were encountered: