]> granicus.if.org Git - clang/commitdiff
Disallow reinterpret_cast from pointer to bool on Windows
authorHans Wennborg <hans@hanshq.net>
Thu, 6 Jun 2013 09:16:36 +0000 (09:16 +0000)
committerHans Wennborg <hans@hanshq.net>
Thu, 6 Jun 2013 09:16:36 +0000 (09:16 +0000)
This became allowed by accident in r131201, but triggers an assert.
That patch added an exception to allow conversion from pointers to
narrow integral types for MSVC compatibility. However, a pointer can
already be converted to bool in a civilized manner; allowing conversion
via reinterpret_cast is a bad idea.

Fixes PR16222.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183394 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaCast.cpp
test/Sema/MicrosoftExtensions.c
test/SemaCXX/MicrosoftExtensions.cpp

index 3f0a1a36e46e2221826b486759c249aeff90a86c..b4e711331970c706b78d3590d2070199a0c2a2b1 100644 (file)
@@ -1813,10 +1813,12 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
     assert(srcIsPtr && "One type must be a pointer");
     // C++ 5.2.10p4: A pointer can be explicitly converted to any integral
     //   type large enough to hold it; except in Microsoft mode, where the
-    //   integral type size doesn't matter.
+    //   integral type size doesn't matter (except we don't allow bool).
+    bool MicrosoftException = Self.getLangOpts().MicrosoftExt &&
+                              !DestType->isBooleanType();
     if ((Self.Context.getTypeSize(SrcType) >
          Self.Context.getTypeSize(DestType)) &&
-         !Self.getLangOpts().MicrosoftExt) {
+         !MicrosoftException) {
       msg = diag::err_bad_reinterpret_cast_small_int;
       return TC_Failed;
     }
index a66d9a9eb0f44139dcd50894c0c5f5ede0915c7d..5215e72b1bac64118cf67b8b394794a156dbbad3 100644 (file)
@@ -76,6 +76,9 @@ void pointer_to_integral_type_conv(char* ptr) {
    short sh = (short)ptr;
    ch = (char)ptr;
    sh = (short)ptr;
+
+   // This is valid ISO C.
+   _Bool b = (_Bool)ptr;
 }
 
 
index 93a6d302ef31b185d980963111c34a9e49f41e4b..c0e7a5ad4c7a8c08a88db2af024ca6df4bf1a388 100644 (file)
@@ -167,8 +167,14 @@ void pointer_to_integral_type_conv(char* ptr) {
    short sh = (short)ptr;
    ch = (char)ptr;
    sh = (short)ptr;
-} 
 
+   // These are valid C++.
+   bool b = (bool)ptr;
+   b = static_cast<bool>(ptr);
+
+   // This is bad.
+   b = reinterpret_cast<bool>(ptr); // expected-error {{cast from pointer to smaller type 'bool' loses information}}
+}
 
 namespace friend_as_a_forward_decl {