This is an archive of the discontinued LLVM Phabricator instance.

Ban implicit _Complex to scalar conversions in C++
AcceptedPublic

Authored by t.p.northover on Jul 24 2017, 2:42 PM.

Details

Reviewers
rsmith
hfinkel
Summary

As part of preparing Clang for a C++14 default we noticed that code like this was accepted and did horrible things in C++11 or earlier modes (i.e. where 1.0if is a _Complex float rather than a UDL):

std::complex<float> var = 1.0if;

This is because 1.0if is implicitly cast to a plain float, discarding the imaginary part. Then the constructor is called with just this real part and a default 0.0f for the imaginary part.

To avoid this surprising behaviour (and to follow GCC's behaviour) this patch bans such conversions in C++ mode. We can't do it in C99 because it's blessed by the standard.

As part of this some OpenMP and warning tests became irrelevant (again, in line with GCC) so I removed them.

My biggest annoyance is the new diagnostic; I couldn't see a way to promote the existing warning to an error in C++ mode so I duplicated the warning and chose at runtime. I'd be happy to rework if there is a better alternative.

Does it look reasonable?

Diff Detail

Event Timeline

t.p.northover created this revision.Jul 24 2017, 2:42 PM

Sorry, uploaded version with slightly wrong tests.

hfinkel added inline comments.
clang/include/clang/Basic/DiagnosticSemaKinds.td
3081

I think that, as an error, we should word this differently. How about:

implicit conversion from %0 to %1 is not permitted in C++

Sounds like an improvement, I've updated the diff.

What's going on with the OpenMP test changes?

What's going on with the OpenMP test changes?

Compound assignment operators like "real /= complex" become illegal under the new rules (in C++) because somewhere there has to be an implicit conversion. I was pretty relieved to discover GCC also rejects the syntax because my change actually messes up the AST quite comprehensively if we wanted it to be legal (OpenMP does some weird stuff building its AST).

hfinkel accepted this revision.Aug 8 2017, 12:16 PM

What's going on with the OpenMP test changes?

Compound assignment operators like "real /= complex" become illegal under the new rules (in C++) because somewhere there has to be an implicit conversion. I was pretty relieved to discover GCC also rejects the syntax because my change actually messes up the AST quite comprehensively if we wanted it to be legal (OpenMP does some weird stuff building its AST).

Okay. LGTM.

This revision is now accepted and ready to land.Aug 8 2017, 12:16 PM
rsmith added inline comments.Aug 10 2017, 4:31 PM
clang/lib/Sema/SemaChecking.cpp
9372

Do we really want to have different semantic rules for code from system macros?

If so, the way we usually do this is with a DefaultError ExtWarn (an off-by-default extension).

clang/test/SemaCXX/warn-absolute-value.cpp
452

Do we have test coverage for this diagnostic in C still? (It seems to be unreachable in C++ now.)