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