[cfe-commits] Greatly improved static_cast error messages
Douglas Gregor
dgregor at apple.com
Fri Nov 7 05:42:22 PST 2008
On Nov 6, 2008, at 3:53 PM, Sebastian Redl wrote:
> Attached patch brings a great improvement in the error messages for
> invalid static_casts. It's not quite trivial, though, so I'm asking
> for a review first.
These *are* greatly improved error messages. Nice!
Of course, you caught my eye with this one:
+ // This may not be entirely in line with the standard. Take for
example:
+ // struct A {};
+ // struct B : virtual A {
+ // B(A&);
+ // };
+ //
+ // void f()
+ // {
+ // (void)static_cast<const B&>(*((A*)0));
+ // }
+ // As far as the standard is concerned, p5 does not apply (A is
virtual), so
+ // p2 should be used instead - "const B& t(*((A*)0));" is perfectly
valid.
+ // However, both GCC and Comeau reject this example, and there's no
reason
+ // to go to absurdly great lengths just to support pathological
examples.
I'm trying to determine what these "absurdly great lengths" actually
would be. As far as I can tell, it means silently rejecting the A->B
downcast and then trying conversion by constructor later on (which
will happen anyway). That makes it harder to give a nice error message
in the common case, right?
The reason for supporting this example, of course, is that it's what
the standard says, and we can smugly add this to our list of things
that we do right when others get them wrong. I'm okay with this patch
going in as-is, despite being non-compliant in this area, but I'd
rather that the comment reflect that this is a problem we're going to
fix, but it isn't a very high priority, e.g., make it a FIXME and drop
from "there's no reason..." to the end.
I guess TryStaticDowncast could have some kind of interface that
allows it to say, "I might have more to complain about later" and, if
that flag gets set and later conversions fail, we can go back through
with a flag that says, "we failed; complain away."
In TryStaticImplicitCast:
+ if (DestType->isRecordType()) {
+ // FIXME: Use an implementation of C++ [over.match.ctor] for this.
+ return TSC_NotApplicable;
+ }
Have you seen PerformInitializationByConstructor? It's a relatively
new addition that, as it says, performs initialization of a class type
by constructor. It should do what you need, although I guess we might
need to split it into Perform/TryInitializationByConstructor.
+ // FIXME: To get a proper error from invalid conversions here, we
need to
+ // reimplement more of this.
+ ImplicitConversionSequence ICS = TryImplicitConversion(SrcExpr,
DestType);
+ return ICS.ConversionKind ==
ImplicitConversionSequence::BadConversion ?
+ TSC_NotApplicable : TSC_Success;
I assume that the problem here is that we don't get good error
messages out of TryImplicitConversion? That's definitely true, and it
has some of the same issues that you've been tackling with static_cast.
Thanks!
- Doug
More information about the cfe-commits
mailing list