Hi rsmith, fraggamuffin,

This modifies Clang to reflect that under pre-C99 ISO C, decimal
constants may have type `unsigned long` even if they do not contain `u`
or `U` in their suffix (C90 subclause 6.1.3.2 paragraph 5). The same is
done for C++ without C++11 which--because of undefined behaviour--allows
for behaviour compatible with ISO C90 in the case of an unsuffixed
decimal literal and is otherwise identical to C90 in its treatment of
integer literals (C++03 subclause 2.13.1 [lex.icon] paragraph 2).

A message is added alongside `ext_integer_literal_too_large_for_signed`
to the `implicitly-unsigned-literal` group to warn on this additional
cause of implicitly unsigned literals.

Fixes PR 16678.

http://reviews.llvm.org/D9794

Files:
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/DiagnosticGroups.td
  lib/Sema/SemaExpr.cpp
  test/Sema/PR16678new32.c
  test/Sema/PR16678new32.cpp
  test/Sema/PR16678new64.c
  test/Sema/PR16678new64.cpp
  test/Sema/PR16678old32.c
  test/Sema/PR16678old32.cpp
  test/Sema/PR16678old64.c
  test/Sema/PR16678old64.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/clang/Basic/DiagnosticCommonKinds.td
===================================================================
--- include/clang/Basic/DiagnosticCommonKinds.td
+++ include/clang/Basic/DiagnosticCommonKinds.td
@@ -115,7 +115,11 @@
 def ext_integer_literal_too_large_for_signed : ExtWarn<
   "integer literal is too large to be represented in a signed integer type, "
   "interpreting as unsigned">,
-  InGroup<DiagGroup<"implicitly-unsigned-literal">>;
+  InGroup<ImplicitlyUnsignedLiteral>;
+def warn_old_implicitly_unsigned_long : Warning<
+  "integer literal is of type unsigned long only when %select{C99|C++11}0 "
+  "or higher is not enabled">,
+  InGroup<ImplicitlyUnsignedLiteral>;
 
 // SEH
 def err_seh_expected_handler : Error<
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -239,6 +239,7 @@
 def : DiagGroup<"nested-externs">;
 def CXX11LongLong : DiagGroup<"c++11-long-long">;
 def LongLong : DiagGroup<"long-long", [CXX11LongLong]>;
+def ImplicitlyUnsignedLiteral : DiagGroup<"implicitly-unsigned-literal">;
 def MethodSignatures : DiagGroup<"method-signatures">;
 def MismatchedParameterTypes : DiagGroup<"mismatched-parameter-types">;
 def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">;
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -3420,6 +3420,14 @@
             Ty = Context.LongTy;
           else if (AllowUnsigned)
             Ty = Context.UnsignedLongTy;
+          // Check according to the rules of C90 6.1.3.2p5. C++03 [lex.icon]p2
+          // is compatible.
+          else if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11) {
+            Diag(Tok.getLocation(), diag::warn_old_implicitly_unsigned_long)
+                << (!getLangOpts().CPlusPlus ? /*NewerStd=C99*/ 0
+                                             : /*NewerStd=C++11*/ 1);
+            Ty = Context.UnsignedLongTy;
+          }
           Width = LongSize;
         }
       }
Index: test/Sema/PR16678new32.c
===================================================================
--- /dev/null
+++ test/Sema/PR16678new32.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -std=c99 -x c %s -verify
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -std=c11 -x c %s -verify
+// expected-no-diagnostics
+
+/******************************************************************************
+ * Test 2^31 as a decimal literal with no suffix and with the "l" and "L" cases.
+ ******************************************************************************/
+
+extern long long x;
+extern __typeof__(2147483648) x;
+extern __typeof__(2147483648l) x;
+extern __typeof__(2147483648L) x;
+
+/******************************************************************************
+ * Test preprocessor arithmetic with 2^31 as a decimal literal with no suffix
+ * and with the "l" and "L" cases.
+ ******************************************************************************/
+
+#define EXPR(X) ((X - X) - 1 < 0)
+
+#if !(EXPR(2147483648) && EXPR(2147483648l) && EXPR(2147483648L))
+#error Unexpected signedness or conversion behavior
+#endif
Index: test/Sema/PR16678new32.cpp
===================================================================
--- /dev/null
+++ test/Sema/PR16678new32.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -std=c++11 -x c++ %s -verify
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -std=c++1y -x c++ %s -verify
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -std=c++1z -x c++ %s -verify
+// expected-no-diagnostics
+
+/******************************************************************************
+ * Test 2^31 as a decimal literal with no suffix and with the "l" and "L" cases.
+ ******************************************************************************/
+
+extern long long x;
+extern __typeof__(2147483648) x;
+extern __typeof__(2147483648l) x;
+extern __typeof__(2147483648L) x;
+
+/******************************************************************************
+ * Test preprocessor arithmetic with 2^31 as a decimal literal with no suffix
+ * and with the "l" and "L" cases.
+ ******************************************************************************/
+
+#define EXPR(X) ((X - X) - 1 < 0)
+
+#if !(EXPR(2147483648) && EXPR(2147483648l) && EXPR(2147483648L))
+#error Unexpected signedness or conversion behavior
+#endif
Index: test/Sema/PR16678new64.c
===================================================================
--- /dev/null
+++ test/Sema/PR16678new64.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -std=c99 -x c %s -verify
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -std=c11 -x c %s -verify
+
+/******************************************************************************
+ * Test 2^31 as a decimal literal with no suffix and with the "l" and "L" cases.
+ ******************************************************************************/
+
+extern long x;
+extern __typeof__(2147483648) x;
+extern __typeof__(2147483648l) x;
+extern __typeof__(2147483648L) x;
+
+/******************************************************************************
+ * Test 2^63 as a decimal literal with no suffix and with the "l" and "L" cases.
+ ******************************************************************************/
+
+extern unsigned long long x64; // status quo, but it is an extension
+extern __typeof__(9223372036854775808) x64; // expected-warning {{integer literal is too large to be represented in a signed integer type, interpreting as unsigned}}
+extern __typeof__(9223372036854775808l) x64; // expected-warning {{integer literal is too large to be represented in a signed integer type, interpreting as unsigned}}
+extern __typeof__(9223372036854775808L) x64; // expected-warning {{integer literal is too large to be represented in a signed integer type, interpreting as unsigned}}
+
+/******************************************************************************
+ * Test preprocessor arithmetic with 2^31 as a decimal literal with no suffix
+ * and with the "l" and "L" cases.
+ ******************************************************************************/
+
+#define EXPR(X) ((X - X) - 1 < 0)
+
+#if !(EXPR(2147483648) && EXPR(2147483648l) && EXPR(2147483648L))
+#error Unexpected signedness or conversion behavior
+#endif
Index: test/Sema/PR16678new64.cpp
===================================================================
--- /dev/null
+++ test/Sema/PR16678new64.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -std=c++11 -x c++ %s -verify
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -std=c++1y -x c++ %s -verify
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -std=c++1z -x c++ %s -verify
+
+/******************************************************************************
+ * Test 2^31 as a decimal literal with no suffix and with the "l" and "L" cases.
+ ******************************************************************************/
+
+extern long x;
+extern __typeof__(2147483648) x;
+extern __typeof__(2147483648l) x;
+extern __typeof__(2147483648L) x;
+
+/******************************************************************************
+ * Test 2^63 as a decimal literal with no suffix and with the "l" and "L" cases.
+ ******************************************************************************/
+
+extern unsigned long long x64; // status quo, but it is an extension
+extern __typeof__(9223372036854775808) x64; // expected-warning {{integer literal is too large to be represented in a signed integer type, interpreting as unsigned}}
+extern __typeof__(9223372036854775808l) x64; // expected-warning {{integer literal is too large to be represented in a signed integer type, interpreting as unsigned}}
+extern __typeof__(9223372036854775808L) x64; // expected-warning {{integer literal is too large to be represented in a signed integer type, interpreting as unsigned}}
+
+/******************************************************************************
+ * Test preprocessor arithmetic with 2^31 as a decimal literal with no suffix
+ * and with the "l" and "L" cases.
+ ******************************************************************************/
+
+#define EXPR(X) ((X - X) - 1 < 0)
+
+#if !(EXPR(2147483648) && EXPR(2147483648l) && EXPR(2147483648L))
+#error Unexpected signedness or conversion behavior
+#endif
Index: test/Sema/PR16678old32.c
===================================================================
--- /dev/null
+++ test/Sema/PR16678old32.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -std=c89 -x c %s -verify
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -std=iso9899:199409 -x c %s -verify
+
+/******************************************************************************
+ * Test 2^31 as a decimal literal with no suffix and with the "l" and "L" cases.
+ *
+ * Under pre-C99 ISO C, unsigned long is attempted for decimal integer literals
+ * that do not have a suffix containing "u" or "U" if the literal does not fit
+ * within the range of int or long. See 6.1.3.2 paragraph 5.
+ ******************************************************************************/
+
+extern unsigned long x;
+extern __typeof__(2147483648) x; // expected-warning {{integer literal is of type unsigned long only when C99 or higher is not enabled}}
+extern __typeof__(2147483648l) x; // expected-warning {{integer literal is of type unsigned long only when C99 or higher is not enabled}}
+extern __typeof__(2147483648L) x; // expected-warning {{integer literal is of type unsigned long only when C99 or higher is not enabled}}
+
+/******************************************************************************
+ * Test preprocessor arithmetic with 2^31 as a decimal literal with no suffix
+ * and with the "l" and "L" cases.
+ *
+ * Note:
+ * Under pre-C99/C++11 ISO C/C++, whether the interpretation of the literal is
+ * affected by the modified range of the signed and unsigned integer types
+ * within the controlling constant expression for conditional inclusion is
+ * unclear.
+ ******************************************************************************/
+
+#define PP_LONG_MAX ((0ul - 1ul) >> 1)
+#define EXPR(X)                                                                \
+  (PP_LONG_MAX >= 0x80000000 || (X - X) - 1 > 0) // either 2^31 fits into a
+                                                 // preprocessor "long" or the
+                                                 // literals in question are
+                                                 // unsigned
+
+#if !(EXPR(2147483648) && EXPR(2147483648l) && EXPR(2147483648L))
+#error Unexpected signedness or conversion behavior
+#endif
Index: test/Sema/PR16678old32.cpp
===================================================================
--- /dev/null
+++ test/Sema/PR16678old32.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -std=c++98 -x c++ %s -verify
+
+/******************************************************************************
+ * Test 2^31 as a decimal literal with no suffix and with the "l" and "L" cases.
+ *
+ * Under pre-C99 ISO C, unsigned long is attempted for decimal integer literals
+ * that do not have a suffix containing "u" or "U" if the literal does not fit
+ * within the range of int or long. See 6.1.3.2 paragraph 5.
+ *
+ * Note:
+ * Under pre-C++11 ISO C++, the same holds if the literal contains an "l" or "L"
+ * in its suffix; otherwise, the behavior is undefined. See 2.13.1 [lex.icon]
+ * paragraph 2.
+ ******************************************************************************/
+
+extern unsigned long x;
+extern __typeof__(2147483648) x; // expected-warning {{integer literal is of type unsigned long only when C++11 or higher is not enabled}}
+extern __typeof__(2147483648l) x; // expected-warning {{integer literal is of type unsigned long only when C++11 or higher is not enabled}}
+extern __typeof__(2147483648L) x; // expected-warning {{integer literal is of type unsigned long only when C++11 or higher is not enabled}}
+
+/******************************************************************************
+ * Test preprocessor arithmetic with 2^31 as a decimal literal with no suffix
+ * and with the "l" and "L" cases.
+ *
+ * Note:
+ * Under pre-C99/C++11 ISO C/C++, whether the interpretation of the literal is
+ * affected by the modified range of the signed and unsigned integer types
+ * within the controlling constant expression for conditional inclusion is
+ * unclear.
+ ******************************************************************************/
+
+#define PP_LONG_MAX ((0ul - 1ul) >> 1)
+#define EXPR(X)                                                                \
+  (PP_LONG_MAX >= 0x80000000 || (X - X) - 1 > 0) // either 2^31 fits into a
+                                                 // preprocessor "long" or the
+                                                 // literals in question are
+                                                 // unsigned
+
+#if !(EXPR(2147483648) && EXPR(2147483648l) && EXPR(2147483648L))
+#error Unexpected signedness or conversion behavior
+#endif
Index: test/Sema/PR16678old64.c
===================================================================
--- /dev/null
+++ test/Sema/PR16678old64.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -std=c89 -x c %s -verify
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -std=iso9899:199409 -x c %s -verify
+
+/******************************************************************************
+ * Test 2^31 as a decimal literal with no suffix and with the "l" and "L" cases.
+ ******************************************************************************/
+
+extern long x;
+extern __typeof__(2147483648) x;
+extern __typeof__(2147483648l) x;
+extern __typeof__(2147483648L) x;
+
+/******************************************************************************
+ * Test 2^63 as a decimal literal with no suffix and with the "l" and "L" cases.
+ *
+ * Under pre-C99 ISO C, unsigned long is attempted for decimal integer literals
+ * that do not have a suffix containing "u" or "U" if the literal does not fit
+ * within the range of int or long. See 6.1.3.2 paragraph 5.
+ ******************************************************************************/
+
+extern unsigned long x64;
+extern __typeof__(9223372036854775808) x64; // expected-warning {{integer literal is of type unsigned long only when C99 or higher is not enabled}}
+extern __typeof__(9223372036854775808l) x64; // expected-warning {{integer literal is of type unsigned long only when C99 or higher is not enabled}}
+extern __typeof__(9223372036854775808L) x64; // expected-warning {{integer literal is of type unsigned long only when C99 or higher is not enabled}}
+
+/******************************************************************************
+ * Test preprocessor arithmetic with 2^31 as a decimal literal with no suffix
+ * and with the "l" and "L" cases.
+ ******************************************************************************/
+
+#define EXPR(X) ((X - X) - 1 < 0)
+
+#if !(EXPR(2147483648) && EXPR(2147483648l) && EXPR(2147483648L))
+#error Unexpected signedness or conversion behavior
+#endif
Index: test/Sema/PR16678old64.cpp
===================================================================
--- /dev/null
+++ test/Sema/PR16678old64.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -std=c++98 -x c++ %s -verify
+
+/******************************************************************************
+ * Test 2^31 as a decimal literal with no suffix and with the "l" and "L" cases.
+ ******************************************************************************/
+
+extern long x;
+extern __typeof__(2147483648) x;
+extern __typeof__(2147483648l) x;
+extern __typeof__(2147483648L) x;
+
+/******************************************************************************
+ * Test 2^63 as a decimal literal with no suffix and with the "l" and "L" cases.
+ *
+ * Under pre-C99 ISO C, unsigned long is attempted for decimal integer literals
+ * that do not have a suffix containing "u" or "U" if the literal does not fit
+ * within the range of int or long. See 6.1.3.2 paragraph 5.
+ *
+ * Note:
+ * Under pre-C++11 ISO C++, the same holds if the literal contains an "l" or "L"
+ * in its suffix; otherwise, the behavior is undefined. See 2.13.1 [lex.icon]
+ * paragraph 2.
+ ******************************************************************************/
+
+extern unsigned long x64;
+extern __typeof__(9223372036854775808) x64; // expected-warning {{integer literal is of type unsigned long only when C++11 or higher is not enabled}}
+extern __typeof__(9223372036854775808l) x64; // expected-warning {{integer literal is of type unsigned long only when C++11 or higher is not enabled}}
+extern __typeof__(9223372036854775808L) x64; // expected-warning {{integer literal is of type unsigned long only when C++11 or higher is not enabled}}
+
+/******************************************************************************
+ * Test preprocessor arithmetic with 2^31 as a decimal literal with no suffix
+ * and with the "l" and "L" cases.
+ ******************************************************************************/
+
+#define EXPR(X) ((X - X) - 1 < 0)
+
+#if !(EXPR(2147483648) && EXPR(2147483648l) && EXPR(2147483648L))
+#error Unexpected signedness or conversion behavior
+#endif
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to