llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.81k stars 11.45k forks source link

Wrong initialization performed with empty initializer list #49903

Open 33ba5f46-8377-4b0d-8784-1d0429f0fe31 opened 3 years ago

33ba5f46-8377-4b0d-8784-1d0429f0fe31 commented 3 years ago
Bugzilla Link 50559
Version unspecified
OS Linux
CC @DougGregor,@efriedma-quic,@predelnik,@rajkumarananthu,@zygoloid

Extended Description

Given code below:

struct S {
  S(std::initializer_list<double>); // #&#8203;1
  S(std::initializer_list<int>);    // #&#8203;2
  S();                              // #&#8203;3
  // ...
};
int main() {
  S s1 = {}; // invoked #&#8203;3
  s1 = {}; // should invoke #&#8203;3 again, but tries to invoke #&#8203;1 or #&#8203;2 and call is ambigious.
}

Code is tried to be miscompiled, s1 should be value initialized due to empty initializer list assignment.

efriedma-quic commented 3 years ago

as it not able to find an overloaded operator function inside the struct S

This isn't right. clang is finding the implicit move assignment and copy assignment operators. It's just incorrectly complaining that they're ambiguous.

If you mess with one of the operators so it isn't viable (for example, declare "S&& operator=(S&&) volatile;"), the code compiles.

rajkumarananthu commented 3 years ago

These are my observations: The statement:

S s1 = {};

the above statement is considered as initialization, this specific type is called list initialization. As you have not specified any value, this instance is called zero initialization or empty initialization(void). As a result it invokes #​3(default constructor).

The statement:

s1 = {};

Here this is considered as an assignment, not as an initialization, so compiler is looking for overloaded assignment operator, as it not able to find an overloaded operator function inside the struct S, it is errors out saying it is not able to find overloaded operator = with operand types S and void

Refernce: https://www.learncpp.com/cpp-tutorial/variable-assignment-and-initialization/

So the compiler is right in this situation.

Please let me know if you have any questions, otherwise you can close this bug as Invalid.

Thanks, Rajkumar Ananthu.

fhahn commented 2 years ago

Still reproduces on current main: https://godbolt.org/z/Mdvne9d5b

llvmbot commented 2 years ago

@llvm/issue-subscribers-clang-frontend