[Bug c++/58119] New: Invalid ambiguous default type conversion with only a single invalid conversion listed.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58119 Bug ID: 58119 Summary: Invalid ambiguous default type conversion with only a single invalid conversion listed. Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tilps at hotmail dot com 'Minimal' test case: template class Silly { public: Silly(type *value) { data_ = value; } operator type*() const { return data_; } template operator Silly() const { return Silly(data_); } private: type *data_; }; int main() { Silly a(nullptr); delete a; } Fails giving: test.cc:20:10: error: ambiguous default type conversion from 'Silly' delete a; ^ test.cc:20:10: error: candidate conversions include 'template Silly::operator Silly() const [with other = other; type = int]' test.cc:20:10: error: type 'class Silly' argument given to 'delete', expected pointer I believe that this code should be considered valid, the only valid type conversion is via the operator type *() which then converts to void* for the delete operator. I don't see any way that Silly could be considered convertible, except via operator type *() - and as far as I was aware, only a single implicit cast operator is allowed to be considered in a type conversion chain. Interestingly, the valid type conversion is not mentioned as a candidate, and the candidate mentioned does not specify which template parameter type it would use for the 'other' template parameter. Ultimately this is a bit of a strange example - I was trying to resurrect some legacy code with a particularly dumb (but heavily used) 'smart pointer' type. But this code did work, at least as recently as 4.6 - and probably back before 3.2.
[Bug c++/98632] New: Warn about unspecified expression ordering for atomics with non-relaxed memory ordering.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98632 Bug ID: 98632 Summary: Warn about unspecified expression ordering for atomics with non-relaxed memory ordering. Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tilps at hotmail dot com Target Milestone: --- C++ defines that execution ordering for expressions is largely unspecified. In cases where there are multiple atomic operations in an expression for which there is no standard required ordering, and if those atomic operations are marked with a non-relaxed memory ordering, it would be useful to have a warning. Since the compiler is technically free to reorder them in-spite of the memory ordering indicating that the user cares about the specific ordering. While it might be able to be argued that the warning should fire for any expression involving just a single atomic and some other expression component that would be unable to be reordered if the sub-expressions had been assigned to locals first, it seems that would be likely to have vastly more false positives than expressions that involve multiple atomic operations. So I would suggest only triggering for expressions involving multiple atomic operations.
[Bug c++/98632] Warn about unspecified expression ordering for atomics with non-relaxed memory ordering.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98632 --- Comment #2 from tilps at hotmail dot com --- *rough sketch* class TaskConsumer { void run() { if (taken_count_.load(std::memory_order_acquire) < task_count_.load(std::memory_order_acquire)) { taken_count_.fetch_add(1, std::memory_order_acq_rel); // ... handle the new task... } } void addTask() { task_count_.fetch_add(1, std::memory_order_acq_rel); } void reset() { task_count_.store(0, std::memory_order_release); taken_count_.store(0, std::memory_order_release); } std::atomic task_count_; std::atomic taken_count_; }; The above is not a 'complete' code sample, just illustrative. One thread is calling 'run' in a loop. Other thread calls reset, then add task some number of times. Waits until it knows the first thread has done all tasks (not covered in the code above, but assume that it is thread-safe and establishes acquire/release ordering as appropriate), then calls reset again and repeats the process. In order for the 'if' statement to behave correctly taken count must be read before task count. If task count is read first it can read the value in task_count_ before reset, but the taken_count_ value after reset. If an optimizer (not necessarily an existing gcc one) decides to reorder the if statement because the standard says order is unspecified and it notices that task_count_ is an earlier memory address to taken_count_ and presumes reordering might give a small performance increase due to sequential memory access and cpu prefetching assumptions... then the code breaks. Thus I would like a warning pointing at that if statement with wording along the lines of: C++ standard does not guarantee ordering of evaluation in this expression, thus the order of atomic operations with non-relaxed memory ordering in this expression is unspecified. Extract them into separate expressions to guarantee that the ordering is consistent with the memory ordering annotations.