Author: Arthur Eubanks
Date: 2020-03-05T15:17:06-08:00
New Revision: cfff4851acc5132c8dcaebca6af92f817e133d66

URL: 
https://github.com/llvm/llvm-project/commit/cfff4851acc5132c8dcaebca6af92f817e133d66
DIFF: 
https://github.com/llvm/llvm-project/commit/cfff4851acc5132c8dcaebca6af92f817e133d66.diff

LOG: Add warnings for casting ptr -> smaller int for C++ in Microsoft mode

Adds warnings to groups recently added in https://reviews.llvm.org/D72231.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D75708

Added: 
    

Modified: 
    clang/lib/Sema/SemaCast.cpp
    clang/test/SemaCXX/MicrosoftExtensions.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 2b3b60e6bde4..17d07c57a412 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -2204,13 +2204,19 @@ static TryCastResult TryReinterpretCast(Sema &Self, 
ExprResult &SrcExpr,
     // 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 (except we don't allow bool).
-    bool MicrosoftException = Self.getLangOpts().MicrosoftExt &&
-                              !DestType->isBooleanType();
     if ((Self.Context.getTypeSize(SrcType) >
-         Self.Context.getTypeSize(DestType)) &&
-         !MicrosoftException) {
-      msg = diag::err_bad_reinterpret_cast_small_int;
-      return TC_Failed;
+         Self.Context.getTypeSize(DestType))) {
+      bool MicrosoftException =
+          Self.getLangOpts().MicrosoftExt && !DestType->isBooleanType();
+      if (MicrosoftException) {
+        unsigned Diag = SrcType->isVoidPointerType()
+                            ? diag::warn_void_pointer_to_int_cast
+                            : diag::warn_pointer_to_int_cast;
+        Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;
+      } else {
+        msg = diag::err_bad_reinterpret_cast_small_int;
+        return TC_Failed;
+      }
     }
     Kind = CK_PointerToIntegral;
     return TC_Success;

diff  --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp 
b/clang/test/SemaCXX/MicrosoftExtensions.cpp
index 4dca1b613421..c9703828366c 100644
--- a/clang/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp
@@ -200,17 +200,31 @@ extern const int static_var; // expected-note {{previous 
declaration is here}}
 static const int static_var = 3; // expected-warning {{redeclaring non-static 
'static_var' as static is a Microsoft extension}}
 
 void pointer_to_integral_type_conv(char* ptr) {
-   char ch = (char)ptr;
-   short sh = (short)ptr;
-   ch = (char)ptr;
-   sh = (short)ptr;
+  char ch = (char)ptr;   // expected-warning {{cast to smaller integer type 
'char' from 'char *'}}
+  short sh = (short)ptr; // expected-warning {{cast to smaller integer type 
'short' from 'char *'}}
+  ch = (char)ptr;        // expected-warning {{cast to smaller integer type 
'char' from 'char *'}}
+  sh = (short)ptr;       // expected-warning {{cast to smaller integer type 
'short' from 'char *'}}
 
-   // These are valid C++.
-   bool b = (bool)ptr;
-   b = static_cast<bool>(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}}
+  // This is bad.
+  b = reinterpret_cast<bool>(ptr); // expected-error {{cast from pointer to 
smaller type 'bool' loses information}}
+}
+
+void void_pointer_to_integral_type_conv(void *ptr) {
+  char ch = (char)ptr;   // expected-warning {{cast to smaller integer type 
'char' from 'void *'}}
+  short sh = (short)ptr; // expected-warning {{cast to smaller integer type 
'short' from 'void *'}}
+  ch = (char)ptr;        // expected-warning {{cast to smaller integer type 
'char' from 'void *'}}
+  sh = (short)ptr;       // expected-warning {{cast to smaller integer type 
'short' from 'void *'}}
+
+  // 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}}
 }
 
 struct PR11150 {


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to