[cfe-dev] Preliminary reinterpret_cast Sema patch

Argiris Kirtzidis akyrtzi at gmail.com
Sun Oct 19 06:22:41 PDT 2008

Sebastian Redl wrote:
> The thing is, compilers implement a curiously hybrid view of the 
> standard.
> 5.2.10/1 says that only the explicitly listed conversions are supported.
> 5.2.10/2 says that conversion to self is allowed, "subject to the 
> restrictions in this section". But 5.2.10 contains only two 
> restrictions: that of not casting away constness (/2) and that of only 
> allowing explicitly listed conversions (/1).
> Let's look at the other paragraphs:
> /4 allows pointer->integral. Obviously, this can't allow conversion to 
> self.
> /5 allows integral->pointer. Same thing.
> /6 allows pointer to function to pointer to function "of different 
> type". This explicitly disallows conversion to self.
> /7 allows pointer to object to pointer to object "of different type". 
> Again, conversion to self is explicitly disallowed.
> /9 allows pointer to member to pointer to member, if both sides are 
> member function or member object types, no mixing. This does not 
> explicitly disallow conversion to self, although it was probably 
> intended, since it would be in keeping with the spirit of the other 
> two paragraphs.
> This means that there are, in my opinion, three valid interpretations 
> of the standard:
> 1) Conversion to self is allowed only for pointers to members. This is 
> the most literal interpretation.
> 2) Conversion to self is not allowed at all. This assumes that /9 is 
> in the spirit of /6 and /7.
> 3) Conversion to self is always allowed. This assumes the note in /2 
> is actually normative and the only restriction it talks about is 
> casting away constness.
> But compilers generally allow conversion to self if the involved types 
> are both pointers, or the equivalent reference cast. GCC allows 
> int*->int*, but not int->int.
> It's easy to follow general practice, of course, but I still think 
> that the other compilers are wrong.

The justification is that integral->integral is not a "explicitly listed 
conversion", so int->int should also be illegal.

>>>   float *fp = reinterpret_cast<float*>(l);
>>>   // Note: should fail on 64-bit, but LLVM is target-agnostic. Is it 
>>> possible
>>>   // to annotate the bytecode to make this fail in native codegen?
>>>   int i = reinterpret_cast<int>(fp);
>> LLVM IR produced by C/C++ cannot be target-agnostic. See: 
>> http://llvm.org/docs/tutorial/LangImpl8.html#targetindep
>> You can use TargetInfo to check whether the above conversion is legal.
> Sad, but makes sense. How do I get a TargetInfo from the Sema?

It's in ASTContext (Context.Target), but a better way is to use 
ASTContext's getTypeSize(QualType T).

>>>   fnptr2 fp2 = reinterpret_cast<fnptr2>(fp);
>>>   // Should fail in C++03 without extensions, succeed with exts or 
>>> in 0x mode.
>>>   void *vp = reinterpret_cast<void*>(fp2);
>> All three compilers accept this; I think Clang should accept it too, 
>> programmers will be unpleasantly surprised if they find this is not 
>> allowed.
> I accept it unless LangInfo.NoExtensions is set. I don't know any 
> switch that actually enables this bit, though - I think -std=c++98 
> should, but it doesn't. I can get rid of the NoExtensions check if you 
> think it's better.
> In addition, I warn if -pedantic is set. This is consistent with GCC's 
> behavior.

Ah never mind, I agree about keeping it consistent with GCC.

If you issue a diagnostic marked with EXTENSION it will have this 
behavior without having to do any explicit checks yourself:
-will not be emitted by default
-will emit a warning at -pedantic
-will emit an error at -pedantic-errors.

And you are right, for C++0x it should probably be allowed without 
pedantic warnings.


More information about the cfe-dev mailing list