[cfe-commits] r158377 - in /cfe/trunk: lib/Sema/SemaOverload.cpp test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp

Richard Smith richard-llvm at metafoo.co.uk
Tue Jun 12 18:07:41 PDT 2012


Author: rsmith
Date: Tue Jun 12 20:07:41 2012
New Revision: 158377

URL: http://llvm.org/viewvc/llvm-project?rev=158377&view=rev
Log:
Add missing narrowing check: converting from a signed integral type to a wider
unsigned type is narrowing if the source is non-constant or negative.

Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=158377&r1=158376&r2=158377&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Jun 12 20:07:41 2012
@@ -389,11 +389,20 @@
     const unsigned ToWidth = Ctx.getIntWidth(ToType);
 
     if (FromWidth > ToWidth ||
-        (FromWidth == ToWidth && FromSigned != ToSigned)) {
+        (FromWidth == ToWidth && FromSigned != ToSigned) ||
+        (FromSigned && !ToSigned)) {
       // Not all values of FromType can be represented in ToType.
       llvm::APSInt InitializerValue;
       const Expr *Initializer = IgnoreNarrowingConversion(Converted);
-      if (Initializer->isIntegerConstantExpr(InitializerValue, Ctx)) {
+      if (!Initializer->isIntegerConstantExpr(InitializerValue, Ctx)) {
+        // Such conversions on variables are always narrowing.
+        return NK_Variable_Narrowing;
+      } else if (FromWidth < ToWidth) {
+        // Negative -> unsigned is narrowing. Otherwise, more bits is never
+        // narrowing.
+        if (InitializerValue.isSigned() && InitializerValue.isNegative())
+          return NK_Constant_Narrowing;
+      } else {
         ConstantValue = APValue(InitializerValue);
 
         // Add a bit to the InitializerValue so we don't have to worry about
@@ -411,9 +420,6 @@
           ConstantType = Initializer->getType();
           return NK_Constant_Narrowing;
         }
-      } else {
-        // Variables are always narrowings.
-        return NK_Variable_Narrowing;
       }
     }
     return NK_Not_Narrowing;

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp?rev=158377&r1=158376&r2=158377&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp Tue Jun 12 20:07:41 2012
@@ -167,6 +167,20 @@
 
   Agg<short> ce1 = { Convert<int>(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}}
   Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}}
+
+  // Negative -> larger unsigned type.
+  unsigned long long ll1 = { -1 }; // expected-error {{cannot be narrowed}} expected-note {{override}}
+  unsigned long long ll2 = { 1 }; // OK
+  unsigned long long ll3 = { s }; // expected-error {{cannot be narrowed}} expected-note {{override}}
+  unsigned long long ll4 = { us }; // OK
+  unsigned long long ll5 = { ll }; // expected-error {{cannot be narrowed}} expected-note {{override}}
+  Agg<unsigned long long> ll6 = { -1 }; // expected-error {{cannot be narrowed}} expected-note {{override}}
+  Agg<unsigned long long> ll7 = { 18446744073709551615ULL }; // OK
+  Agg<unsigned long long> ll8 = { __int128(18446744073709551615ULL) + 1 }; // expected-error {{cannot be narrowed}} expected-note {{override}} expected-warning {{changes value}}
+  signed char c = 'x';
+  unsigned short usc1 = { c }; // expected-error {{cannot be narrowed}} expected-note {{override}}
+  unsigned short usc2 = { (signed char)'x' }; // OK
+  unsigned short usc3 = { (signed char)-1 }; // expected-error {{cannot be narrowed}} expected-note {{override}}
 }
 
 // Be sure that type- and value-dependent expressions in templates get the error





More information about the cfe-commits mailing list